What does ^:internal mean in clojure? e.g. the macro defnilsafe defined in arrows.clj(https://github.com/rplevy/swiss-arrows/blob/1.0.0/src/swiss/arrows.clj) has ^:internal between defmacro and the macro name defnilsafe.
I've never seen that before.
As #leetwinksi said, it appears to be an "internal" note-keeping thing by the authors. Pretty non-standard and I have no idea about the intended usage.
Please remember: metadata is "stuff that doesn't affect equality". It is a kind of "escape hatch" where you can append information that won't affect an equality comparison. It is of very limited use.
Related
My Problem
I'm currently writing a REST-API which is supposed to take JSON requests and work with an intern library we use. The main usage will be to either run the server with a web interface or to possibly use another language to work with the API since Clojure isn't common elsewhere.
In order to achieve this, the JSON request contains data and a functionname, which is run with resolve, since I'm supposed to make it so that we don't have to change the API each time a function is added/removed.
Now the actual question is: How can I make sure the function I run combined with it's argument dosen't destroy the whole thing?
So, what did I try already?
Now, I've actually told only half the truth until now: I don't use resolve, I use ns-resolve. My first intuition was to create a seperate file which will load in all namespaces from the library, there's nothing malicious you could do with those. The problem is, I want only those functions and I'm not aware of any way to remove clojure.core functions. I could do a blacklist for those but whitelisting would be a whole lot easier. Not to mention I could never find all core functions I actually should be blacklisting.
The oher thing is the input.
Again I've got a basic idea which is to sanitize the input to replace all sort of brackets just to make sure the input isn't other clojure code which would just bypass the namespace restriction from above. But would this actually be enough? I've got not much experience in breaking things.
Another concern I've heard is that some functions could run the input as argument long before intended. The server works with ring and its JSON extension.
JSON should only give strings, numbers, booleans and nil as atomic data types. I conclude each possible malicious input should be a string at my end - besides resolve, is there any function which could have the side effect of running such input?
Since they are string: Is there even a concern to be had with the data at all?
I would strongly advise to use a whitelisting approach for functions, and not to evaluate anything else.
You could maybe add a metadata flag to the exposed functions that you check where you resolve them.
Everything else should just be data; don't evaluate it.
Probably you want to look into the following:
How to determine public functions from a given namespace. This will give you a list of the valid functions names that your API can accept as part of the input. Here's a sample:
user=> (ns-publics (symbol "clojure.string"))
{ends-with? #'clojure.string/ends-with?, capitalize #'clojure.string/capitalize, reverse #'clojure.string/reverse, join #'clojure.string/join, replace-first #'clojure.string/replace-first, starts-with? #'clojure.string/starts-with?, escape #'clojure.string/escape, last-index-of #'clojure.string/last-index-of, re-quote-replacement #'clojure.string/re-quote-replacement, includes? #'clojure.string/includes?, replace #'clojure.string/replace, split-lines #'clojure.string/split-lines, lower-case #'clojure.string/lower-case, trim-newline #'clojure.string/trim-newline, upper-case #'clojure.string/upper-case, split #'clojure.string/split, trimr #'clojure.string/trimr, index-of #'clojure.string/index-of, trim #'clojure.string/trim, triml #'clojure.string/triml, blank? #'clojure.string/blank?}
You probably want to use the keys from the map above (in the namespace that applies to your use case) to validate the input, because you can "escape" the ns-resolve namespace if you fully qualify the function name:
user=> ((ns-resolve (symbol "clojure.string") (symbol "reverse")) "hello")
"olleh"
user=> ((ns-resolve (symbol "clojure.string") (symbol "clojure.core/reverse")) "hello")
(\o \l \l \e \h) ;; Called Clojure's own reverse, probably you don't want to allow this
Now, with that being said, I'm going to offer you some free advice:
I'm supposed to make it so that we don't have to change the API each time a function is added/removed
If you have watched some of Rich Hickey's talks you'll know that API changes are a sensible topic. In general you should think carefully before adding new functions or thinking of deleting any, because it sounds like your team is willing to cut corners on getting clients of the API together on the same page.
Unless your clients can discover dynamically what functions are available (maybe you'll expose some API?), it sounds like you will be open to receiving requests you cannot fulfill because the functions have changed or could be removed.
I need a function that can tell whether a symbol is pointing to a special form or a macro.
I found the function? function in the clojure.test namespace, so could use that, but I'm hesitant to use it because it seems to be intended only for testing purposes. Is it okay to use it for normal code? If not, how can I accomplish my goal.
As noted the comments, fn? does not work because it only works on functions themselves, not the symbols that point to them.
If it does what you want, use it. It's in clojure.test because it wasn't expected to be useful for non-test code, but if it's the best function for your particular use case, there's no reason to hamper yourself just because of where the function is located. In other words, clojure.test is separate from clojure.core for organization, not because it should only ever be used for tests.
you can find all special form, :-)
(defn special-symbol?
[s]
(contains? (. clojure.lang.Compiler specials) s))
They say that use exclamation marks when naming impure functions.
But I don't exactly understand the "impure" functions. Are they
functions change state of their arguments (via reset!, alter, java-object-methods, ...)
functions occur side-effect (for example, print, spit, ...)
or both?
Obviously, official clojure apis don't have bang!s on every case above. I wonder when should I put them and need your help to make my code saner.
I would say you don't need to put ! on every impure function. Community Clojure Style Guide recommends:
The names of functions/macros that are not safe in STM transactions
should end with an exclamation mark.
So, basically, end with ! functions that change state for atoms, metadata, vars, transients, agents and io as well.
Thanks to #noisesmith for update.
Here is my article answering your question https://clojure.wladyka.eu/posts/when-use-exclamation-mark/
In simple explanation the rule is like that:
(create-user! ...) has additional effects if you run it more than once with the same input. For example send e-mail each time or create +1 user.
(create-user ...) wouldn’t have additional effects even if you run this many times with the same input.
If it is still not clear think about this:
(create-user! ...) vs (create-user-only-if-not-exist ...).
Can anyone explain or point me to where I can find clojure's naming conventions for:
File names
Functions (From what I understand, function names are simply dash separated values)
Variables
You might want to look at the Clojure library coding standards on the developer Wiki - this is probably the most comprehensive list that I've seen.
Update: link above seems to be dead, consider instead: https://clojure.org/dev/contrib_howto#_coding_guidelines
To your specific points:
File names are lowercase, and stored in a directory structure to match the namespace, and end in .clj e.g. "my/special/namespace.clj
Functions are dash-separated-lowercase-words, ideally descriptively chosen so that your code is clear and self-documenting. Don't be afraid to re-use good function names in different namespaces (that is what namespaces are for!).
Variables (by which I assume you mean parameters, let-bound variables etc.) are also usually dash-separated-lowercase-words. Since code-is-data, I think it is appropriate that functions and data have the same naming convention :-)
You might want to take a look at this non official style guide.
There are some interesting guidelines on naming written by Stuart Sierra which suggest that:
pure functions should be nouns describing the return value (age instead of calculate-age)
side-effecting functions should be verbs describing the action (create- for constructing and get- for retrieving), reserving the bang swap! changes to mutable references.
verbs that can also be nouns should be distinguished as verb phrases (send-message instead of message)
coercions should name the output type without an arrow prefix (connection instead of ->connection) except when the input type must be explicit (input-type->output-type)
namespace aliases can save on repetition (products/price instead of products/product-price) and prevent local clashes in let bindings
functions returning functions should have the -fn suffix
There is an interesting set of naming conventions documented in a comment by
Taoensso in his
Encore library.
He proposes names using ! for side-effects, ? for booleans,
$ for expensive operations, _ as dereffable,
* for macros; plus a few other combos.
Even though you didn't ask for it explicitly, I'll explain what I've seen for protocol naming conventions.
Typically, the name starts with an uppercase "I" and then the rest is camel case, where the first letter of each word is capitalized, and the rest is lower case. For example, I want to define a protocol for rocket ships, I'd use the name IRocketShip
I've also seen 'A' instead of 'I' used, probably to represent the word 'abstract'.
In C++ is there any function that returns "true" when the variable is defined or false in vice versa. Something like this:
bool isDefined(string varName)
{
if (a variable called "varName" is defined)
return true;
else
return false;
}
C++ is not a dynamic language. Which means, that the answer is no. You know this at compile time, not runtime.
There is no such a thing in runtime as it doesn't make sense in a non-dynamic language as C++.
However you can use it inside a sizeof to test if it exists on compile time without side-effects.
(void)sizeof(variable);
That will stop compilation if var doesn't exist.
As already stated, the C++ runtime system does not support the querying of whether or not a variable is declared or not. In general a C++ binary doesn't contain information on variable symbols or their mappings to their location. Technically, this information would be available in a binary compiled with debugging information, and you could certainly query the debugging information to see if a variable name is present at a given location in code, but it would be a dirty hack at best (If you're curious to see what it might look at, I posted a terrible snippet # Call a function named in a string variable in C which calls a C function by a string using the DWARF debugging information. Doing something like this is not advised)
Microsoft has two extensions to C++ named: __if_exists and __if_not_exists. They can be useful in some cases, but they don't take string arguments.
If you really need such a functionality you can add all your variables to a set and then query that set for variable existance.
Already mentioned that C++ doesn't provide such facility.
On the other hand there are cases where the OS implement mechanisms close to isDefined(),
like the GetProcAddress Function, on Windows.
No. It's not like you have a runtime system around C++ which keeps remembers variables with names in some sort of table (meta data) and lets you access a variable through a dynamically generated string. If you want this, you have to build it yourself, for example using a std::map that maps strings to some objects.
Some compile-time mechanism would fit into the language. But I don't think that it would be any useful.
In order to achieve this first you need to implement a dynamic variable handling system, or at least find some on the internet. As previously mentioned the C++ is designed to be a native language so there are no built-in facilities to do this.
What I can suggest for the most easy solution to create a std::map with string keys storing global variables of interest with a boost::any, wxVariant or something similar, and store your variables in this map. You can make your life a bit easier with a little preprocessor directive to define a variables by their name, so you don't need to retype the name of the variable twice. Also, to make life easier I suggest to create a little inline function which access this variable map, and checks if the given string key is contained by the map.
There are implementation such a functionality in many places, the runtime property handling systems are available in different fashion, but if you need just this functionality I suggest to implement by yourself, because most of these solutions are quite general what you probably don't need.
You can make such function, but it wouldn't operate strings. You would have to send variable name. Such a function would try to add 0 to the variable. If it doesn't exists, an error would occur, so you might want to try to make exception handling with try...throw...catch . But because I'm on the phone, I don't know if this wouldn't throw an error anyways when trying to send non-existing variable to the function...