Is it possible to specify a default value for proc fcmp function parameters? Something like this:
proc fcmp outlib=work.funcs.funcs;
function my_func(param1, param2='default_value_here' $);
* DO STUFF;
endsub;
run;
From the documentation and the error messages I'm receiving, I'm not seeing anything that would indicate that it is supported but it seems like it would be a big oversight if that is the case.
SAS 9.4TSM4
It's not possible in the way you describe (as in, obviously, you could emulate a default by applying equivalent logic in the function itself). The thing is, if there was a default, it could not be invoked..
You see, proc fcmp does not support 'optional' arguments (except the VARARGS array). So you would always have to supply a value (which could include missing or a null reference), hence the default would never be applied.
If this ever comes up in a SASware ballot, it gets my vote - optional arguments should definitely be an option in fcmp!
Related
I'm working with an older Fortran code using subroutine calls like this:
call sub(A,,C)
With the corresponding subroutine of the form:
subroutine sub(A,B,C)
So in practice the argument B is optionally omitted here.
However, I am now creating explicit interfaces via the compiler options /warn:interface /gen-interface. I do this to debug interface errors in the code. This results in the following error (from Intel Visual Fortran compiler 19.1.0057.16):
error #8127: A null argument is not permitted when calling a Fortran routine which has an explicit interface defined. [sub]
I could make the argument B optional and move it to the end of the argument list. This would involve updating a lot of function calls. Also, I am not sure if it works in general, as e.g. several arguments may be omitted in this way in different combinations for different function calls.
What is the correct way to modernise the above code to work correctly with explicit interfaces?
Edit: The use of two consecutive commas (,,) is also a deprecated (?) language feature denoting a null data item. From the Oracle Fortran 77 language reference:
A null data item is denoted by two consecutive commas, and it means the corresponding array element or complex variable value is not to be changed. Null data item can be used with array elements or complex variables only. One null data item represents an entire complex constant; you cannot use it for either part of a complex constant.
In the comments below it was noted that this relates to the data input process, and does not apply to my problem.
The Compaq Fortran for OpenVMS manual (Compaq Fortran is a predecesor of Intel Fortran, but OpenVMS is a different operating system) has this:
If you do not want to specify a value for a required parameter, you
can pass a null argument by inserting a comma (,) as a placeholder in
the argument list. If the routine requires any passing mechanism other
than the default, you must specify the passing mechanism in the CALL
statement or the function call.
My understanding is that this feature would most likely be useful when calling procedures created in other programming languages. For example various system calls or other calls to procedures written in C. Such are also the examples offered by the Compaq Fortran manual. You can also see it in the VSI Fortran for OpenVMS manual.
The Oracle Fortran manual calls this a Fortran 77 feature accessible with a -f77 flag:
Allow null actual arguments. For example: CALL FOO(I,,,J) has two null
arguments between the first I and the final J argument.
But this is not and never has been legal Fortran. Under the hood a null pointer is passed instead if the address of an actual argument.
The way to modernize it is to go to Fortran 90 and later and use optional arguments.
subroutine sub(A,B,C)
...
real, optional :: B
In Fortran 2018 this can also be used for procedures written in other programming languages thanks to the Fortran-C interoperability and bind(C). One defines it appropriately in the interface block for such a procedure.
The call with an actual argument with B not present looks like:
call SUB(A_actual,C=C_actual)
These are the named ("keyword") arguments, also introduced in Fortran 90. You can also use them when all actual arguments are present.
E.g., Fortran 90 function with no arguments? How does FORTRAN interact with optional arguments?
The following code compiles just fine and produces the string "abc":
fmt::format("abc", fmt::arg("x", 42));
godbolt
So it looks like named arguments that are missing in the format string are just ignored.
My question is: Is that by design or is it a bug?
I'm asking because I'm having a use case for this "feature". So I want to make sure that this is neither UB nor that it will be "fixed" in future.
I already skimmed through the docs but couldn't find this use case.
This is by design. Unused formatting arguments are essentially the same as unused arguments to any other function and are not an error. This is the case in {fmt} and Python's str.format it is modeled after as well as printf.
Thanks to #selbie, a more clear question is
I've got some magic number or string I need to reference in code. There's a good chance one of the platform header files has already defined this value as an existing macro. And if so, how would I discover the macro with another name, so I don't end up duplicating it was another name?
We know that macro can be computed (or replaced in fact?) in compile time. So I want to know if there any way to search macro name by its value?
Here is a example. When I parse the USN record, I find that FileReferenceNumber of the root of driver is always 1407374883553285, so I would like to check whether it is defined in XXX.h previously, then I don't need to define another one.
By the way, if we can search macro, how about constexpr?
Gcc and clang will print out a list of #defines if you invoke them with the options -E -dM. (If you don't use -E, -dM does something else.)
Unfortunately, macros and arithmetic expressions in the macro replacement texts are not expanded / evaluated, so you'll only be able to find the value if you know it's textual representation. Still, it's a first step.
That won't work for enum member values and constexprs. I don't think there is any way to search for those which doesn't involve using some C parsing library to build a symbol table. Such libraries exist, but they're not necessarily well-documented, stable, or easy to use.
Lisp/Clojure code have consistency in their syntax and it is a plus point as one doesn't need to understand various different constructs.
But at times It is easier to understand by looking at a piece of code just by the different syntax being used like this is a switch case or this is the pattern matching construct etc without actually reading the text.
I have started out with Clojure couple of months ago and I have realized I can't understand the code without reading the name of the form and then googling whether it is a macro or a function and how it works.
So it turns out that, a piece of Clojure code, irrespective fo the uniformity of the syntax isn't uniform.
It may seem like a function but if at all it is a macro then it might not be evaluating all its arguments.
Is there a naming convention or indentation style that all macros use so it is easier for someone to grasp by the name what is going on ?
The most useful intuition in my opinion comes from understanding the purpose of a given operator / Var. Well-designed macros simply could not be written as functions and still offer the same functionality with the same syntax, for if they could, they would in fact be written as functions (see the "well-designed" part above!).1 So, if you're dealing with a construct which couldn't possibly be a regular function, then you know it isn't; otherwise it likely is.
Additionally, the usual ways of learning about the Vars exported by a library tell you whether you're dealing with a macro or a function up front. That is true of doc ((doc foo) says that foo is a macro near the top of its output if that is indeed the case), source (since it gives you the entire code) and M-. (jump to definition in Emacs with nrepl.el or swank-clojure; M-, jumps back). Documentation may be expected to mention what is a macro and what isn't (except that's not necessarily true of docstrings, since all usual ways of accessing a docstring already tell you whether you're dealing with a macro, as explained above).
If you're skimming a body of code with the intention of forming a rough understanding of what it probably does on the assumption that the various operators perform the functions suggested by their names, then either (1) the names are suggestive enough and you get an idea of what's intended by the code, so you don't even need to care which operators happen to be macros, or (2) the names are not suggestive enough, so you'll need to dive into the docs or the source for some of the operators anyway, and then the first thing you'll learn is which of them are registered as macros.
Finally, there is no single naming style for macros, although there are certain conventions specific to particular use cases. For example with-foo-style constructs tend to be convenience macros whose purpose is to simplify dealing with resources of type foo; dofoo-style constructs tend to be macros which take a body of expressions to be executed (how many times and with which additional context set up depends on the macro; the most basic member of this family, do, is actually a special form rather than a macro); deffoo-style constructs introduce new Vars or type-like entities.
It's worth pointing out that similar patterns are sometimes broken. For instance, most threading constructs (-> & Co.) are macros, but xml-> from clojure.data.zip.xml is a function. That makes perfect sense when one considers the functionality provided, which brings us back to the point about the purpose of an operator being the most useful source of intuition.
1 There might be some exceptions to this rule. One would expect these to be documented. Some projects are of course not documented at all (or very nearly so); here the issue goes away completely, since one must go to the source to make sense of things anyway.
There are two attributes that typically distinguish a macro (or sometimes special form) from a function:
When the form does some sort of binding (i.e. declaring new identifiers for later use)
When some of the arguments are evaluated lazily
Examples of the first case are let, letfn, binding and with-local-vars. Strangely though, defn is defined as a function, but I'm pretty sure it has something to do with Clojure's bootstrapping process (defn is defined before defmacro is defined).
Examples of the second would be and, or and lazy-seq. In all these constructs, the arguments are evaluated lazily by either putting them in conditional branches (like if) or moving them inside a function body.
Both of those attributes are really just manifestations of the macro manipulating the Clojure syntax. I don't think the threading macros (-> and ->>) fit very well into either of those categories, but the nil-safe versions (-?> and -?>>) kind of fall under having lazy arguments.
As far as I know there is no enforced naming convention.
As a rule of thumb, functions are preferred wherever possible, but macros can sometimes be spotted when they follow the pattern def<something> for setting up a something or with-<resource> for doing something with an open resource.
Because of this, you may find clojure's doc macro helpful. It will tell you whether a form is a macro/function/special form, as well as give it's arg list and doc string (if present). For example
(use 'clojure.repl)
(doc and)
Will print the following to the repl.
clojure.core/and
([] [x] [x & next])
Macro
Evaluates exprs one at a time, from left to right. If a form
returns logical false (nil or false), and returns that value and
doesn't evaluate any of the other expressions, otherwise it returns
the value of the last expr. (and) returns true.
Some editors (e.g. emacs) will provide this documentation as a pop-up or on a key combination, which makes accessing it (and reading) much faster.
Pretty simple question I think but I'm having trouble finding any discussion on it at all anywhere on the web. I've seen the triple-dot's as function parameters multiple times throughout the years and I've always just thought it meant "and whatever you would stick here." Until last night, when I decided to try to compile a function with them. To my surprise, it compiled without warnings or errors on MSVC2010. Or at least, it appeared to. I'm not really sure, so I figured I'd ask here.
They are va_args, or variable number of arguments. See for example The C book
Triple dots means the function is variadic (i.e. accepts a variable number of parameters). However to be used there should be at least a parameter... so having just "..." isn't an usable portable declaration.
Sometimes variadic function declarations are used in C++ template trickery just because of the resolution precedence of overloads (i.e. those functions are declared just to make a certain template instantiation to fail or succeed, the variadic function themselves are not implemented). This technique is named Substitution failure is not an error (SFINAE).
It's called ellipses - basically saying that function accepts any number of arguments of any non-class type.
It means that the types of arguments, and the number of them are unspecified. A concrete example with which you are probably familiar would be something like printf(char *, ...)
If you use printf, you can put whatever you like after the format string, and it is not enforced by the compiler.
e.g. printf("%s:%s",8), gets through the compiler just the same as if the "expected" arguments are provided printf("%s:%s", "stringA", "stringB").
Unless really necessary, it should be avoided, as it creates the potential for a run time error to occur, where it might otherwise have been picked up at compile time. If there is a finite, enumerable variation in the arguments your function can accept, then it is better to enumerate them by overloading.