The docs say that ! is "Boolean not. Implements three-valued logic" and ~ is "Bitwise not."
When should one be used versus the other?
There is a similar question for Python about comparison operators, but I am not sure where the languages may differ.
As you say, ! is boolean not and ~ is bitwise not. This ends up being a bit redundant since bitwise not for booleans is just boolean not so anywhere you can use ! you should also be able to use ~. (This is always true with standard Julia should remain true as long as package don't addg methods that don't conform to the intended meaning of these operators.) So if you're a Matlab programmer, for example, and you're used to using ~ for boolean not, then you can keep doing that. My suggestion, however, would be to be as precise in your meaning as you can be: if you expect the argument to be boolean, use ! so that you get an error if it isn't. Use ~ if you expect the argument to be an integer and want to flip its bits. But frankly it's no big deal to use ~ for booleans. If it really matters that the argument is boolean, like if it's being used in a conditional, then the error will show up soon anyway.
There was a discussion in the lead up to the 1.0 release about removing ! from the language and using ~ for boolean negation instead, but we ended up keeping ! because it's familiar from languages like C and C++ and giving it any other meaning would be actively confusing. But it's telling that removing it was an option in the first place.
Related
I am trying to learn the Isar language (as of Isabelle 2020), and understand the note command. It seems to be a fundamental element of the language since a lot of the "Derived elements" are defined based on it.
I am not sure what it does in terms of the equivalents of English:
When it is necessary to note something? Aren't all the facts and/or assumptions known at this point of time automatically used, or do I have to explicit note certain facts before I can use them? If so, which ones do and do not need to be noted?
What are the things to be noted?
In the documentation Isar-ref.PDF, appendix A1.2 (pp319), under "Primitives", it says:
note a = b reconsider and declare facts
so it seems that an equality is to be noted.
Then, in A 1.3 in the same page, it says:
from a ≡ note a then
...
from this ≡ then
Here note doesn't seem to work on an equality. Also, there seems to be a endless loop.
from a = note a then = note a from this = note a note this then ...
(then expands to from and back to then).
then on the same page, there is:
also ~ note calculation = this
In English, the word "also" (and to some extent "note that") is optional. This is partly why it is so confusing to me here because it seems to be required, and I am not sure what it does. (I can understand other things such as assume as it moves some facts into the context.)
I've seen this and that used in a note command (e.g. in here Why are the following trivial self-equalities needed in the Isabelle/Isar proof?). This confused me a lot.
Is there a dictionary (English dictionary) style explanation somewhere in terms of what note does on the things (this, that, calculation etc.)?
,... and why is note required?
(The above appendix is the closest thing to a specification I could find.)
No one ever uses that in the way of the question. It hurts to look at that proof. The Isar ref is telling you how things are defined internally, but it is a terrible introduction to Isar. Don't read it. Forget everything you read there. Really.
The right way to start Isar is the prog-prove. Or slides used for teaching.
No facts are used implicitly. Isabelle only uses the facts that you tell it to use. That is why you need using or to pass theorems as argument to tactics.
The usual way to use note is to give a name to something that does not have a name yet, like:
case Suc
note meaningfull_name_one = this(1) and meaningfull_name_two = this(2)
or variants of that. This allows you to refer to theorems by name meaningfull_name_one instead of writing down the full expression. It is not necessary, but easier (also maintenance-wise). When you have 10 assumptions, you don't want to use prems(1) or Suc(8) or whatever.
As mentioned #ManuelEberl
note [simp] = ...
is useful to locally declare a theorem as simp.
Short summary:
this ::= last fact
note H = ... ::= name facts
that ::= name of the fact generate by obtain/obtain
Don't ever use calculation directly.
It is possible to abuse note like in question, by not giving a name to things and relying on its side effects. Don't do it.
One reason is that you can create new theorems with low-level operations such as [OF _]. To simplify reusing such a theorem, you can give it a name.
I have an array of boolean values and I want to get the logical and of all elements. What is the most efficient way to do that?
I tried
&([true,false,false]...)
but it throws the error:
syntax: malformed expression
Surprisingly (at least to me) the following expression
|([true,false,false]...)
evaluates to true. So how do I do that? Right now I use a bunch of nots to do that, but this is very unsatisfactory.
Also is this actually better than just looping through all the elements?
Most probably this behavior of & is caused by deprecated ccall functionality where & was used in front of a variable. As explained in the comments above:
you can wrap & in parentheses to make it work as expected(&)([true,false,false]...); however, this is not efficient as you have do splat the passed argument;
if your arguments are all Boll then all function is a recommended way to perform logical and;
if you would need bitwise and then reduce(&, [true,false,false]) is a nice solution as phg indicated.
In CL, we have many operators to check for equality that depend on the data type: =, string-equal, char=, then equal, eql and whatnot, so on for other data types, and the same for comparison operators (edit don't forget to answer about these please :) do we have generic <, > etc ? can we make them work for another object ?)
However the language has mechanisms to make them generic, for example generics (defgeneric, defmethod) as described in Practical Common Lisp. I imagine very well the same == operator that will work on integers, strings and characters, at least !
There have been work in that direction: https://common-lisp.net/project/cdr/document/8/cleqcmp.html
I see this as a major frustration, and even a wall, for beginners (of which I am), specially we who come from other languages like python where we use one equality operator (==) for every equality check (with the help of objects to make it so on custom types).
I read a blog post (not a monad tutorial, great serie) today pointing this. The guy moved to Clojure, for other reasons too of course, where there is one (or two?) operators.
So why is it so ? Is there any good reasons ? I can't even find a third party library, not even on CL21. edit: cl21 has this sort of generic operators, of course.
On other SO questions I read about performance. First, this won't apply to the little code I'll write so I don't care, and if you think so do you have figures to make your point ?
edit: despite the tone of the answers, it looks like there is not ;) We discuss in comments.
Kent Pitman has written an interesting article that tackles this subject: The Best of intentions, EQUAL rights — and wrongs — in Lisp.
And also note that EQUAL does work on integers, strings and characters. EQUALP also works for lists, vectors and hash tables an other Common Lisp types but objects… For some definition of work. The note at the end of the EQUALP page has a nice answer to your question:
Object equality is not a concept for which there is a uniquely determined correct algorithm. The appropriateness of an equality predicate can be judged only in the context of the needs of some particular program. Although these functions take any type of argument and their names sound very generic, equal and equalp are not appropriate for every application.
Specifically note that there is a trick in my last “works” definition.
A newer library adds generic interfaces to standard Common Lisp functions: https://github.com/alex-gutev/generic-cl/
GENERIC-CL provides a generic function wrapper over various functions in the Common Lisp standard, such as equality predicates and sequence operations. The goal of the wrapper is to provide a standard interface to common operations, such as testing for the equality of two objects, which is extensible to user-defined types.
It does this for equality, comparison, arithmetic, objects, iterators, sequences, hash-tables, math functions,…
So one can define his own + operator for example.
Yes we have! eq works with all values and it works all the time. It does not depend on the data type at all. It is exactly what you are looking for. It's like the is operator in python. It must be exactly what you were looking for? All the other ones agree with eq when it's t, however they tend to be t for totally different values that have various levels of similarities.
(defparameter *a* "this is a string")
(defparameter *b* *a*)
(defparameter *c* "this is a string")
(defparameter *d* "THIS IS A STRING")
All of these are equalp since they contain the same meaning. equalp is perhaps the sloppiest of equal functions. I don't think 2 and 2.0 are the same, but equalp does. In my mind 2 is 2 while 2.0 is somewhere between 1.95 and 2.04. you see they are not the same.
equal understands me. (equal *c* *d*) is definitely nil and that is good. However it returns t for (equal *a* *c*) as well. Both are arrays of characters and each character are the same value, however the two strings are not the same object. they just happen to look the same.
Notice I'm using string here for every single one of them. We have 4 equal functions that tells you if two values have something in common, but only eq tells you if they are the same.
None of these are type specific. They work on all types, however they are not generics since they were around long before that was added in the language. You could perhaps make 3-4 generic equal functions but would they really be any better than the ones we already have?
Fortunately CL21 introduces (more) generic operators, particularly for sequences it defines length, append, setf, first, rest, subseq, replace, take, drop, fill, take-while, drop-while, last, butlast, find-if, search, remove-if, delete-if, reverse, reduce, sort, split, join, remove-duplicates, every, some, map, sum (and some more). Unfortunately the doc isn't great, it's best to look at the sources. Those should work at least for strings, lists, vectors and define methods of the new abstract-sequence.
see also
https://github.com/cl21/cl21/wiki
https://lispcookbook.github.io/cl-cookbook/cl21.html
In various web pages, I see references to jq functions with a slash and a number following them. For example:
walk/1
I found the above notation used on a stackoverflow page.
I could not find in the jq Manual page a definition as to what this notation means. I'm guessing it might indicate that the walk function that takes 1 argument. If so, I wonder why a more meaningful notation isn't used such as is used with signatures in C++, Java, and other languages:
<function>(type1, type2, ..., typeN)
Can anyone confirm what the notation <function>/<number> means? Are other variants used?
The notation name/arity gives the name and arity of the function. "arity" is the number of arguments (i.e., parameters), so for example explode/0 means you'd just write explode without any arguments, and map/1 means you'd write something like map(f).
The fact that 0-arity functions are invoked by name, without any parentheses, makes the notation especially handy. The fact that a function name can have multiple definitions at any one time (each definition having a distinct arity) makes it easy to distinguish between them.
This notation is not used in jq programs, but it is used in the output of the (new) built-in filter, builtins/0.
By contrast, in some other programming languages, it (or some close variant, e.g. module:name/arity in Erlang) is also part of the language.
Why?
There are various difficulties which typically arise when attempting to graft a notation that's suitable for languages in which method-dispatch is based on types onto ones in which dispatch is based solely on arity.
The first, as already noted, has to do with 0-arity functions. This is especially problematic for jq as 0-arity functions are invoked in jq without parentheses.
The second is that, in general, jq functions do not require their arguments to be any one jq type. Having to write something like nth(string+number) rather than just nth/1 would be tedious at best.
This is why the manual strenuously avoids using "name(type)"-style notation. Thus we see, for example, startswith(str), rather than startswith(string). That is, the parameter names in the documentation are clearly just names, though of course they often give strong type hints.
If you're wondering why the 'name/arity' convention isn't documented in the manual, it's probably largely because the documentation was mostly written before jq supported multi-arity functions.
In summary -- any notational scheme can be made to work, but name/arity is (1) concise; (2) precise in the jq context; (3) easy-to-learn; and (4) widely in use for arity-oriented languages, at least on this planet.
I was wondering about the use ternary operators outside of programming. For example, in those pesky calculus classes that are required for a CS degree. Could a person describe something like a hyperbolic function with a ternary operator like this:
1/x ? 1/x : infinity;
This assumes that x is a positive float and should say that if x != 0 then the function returns 1/x, otherwise it returns infinity. Would this circumvent the whole need for limits?
I'm not entirely certian as to the specific question, but yes, a ternary can answer any question posed as 'if/else' or 'if and only if, else'. Traditionally however, math is not written in a conditional format with any real flow control. 'if' and other flow control mechanisms let code execute in differant ways, but with most math, the flow is the same; just the results differ.
Mathematically, any operator can be equivalently described as a function, as in a + b = add(a,b); note that this is true for programming as well. In either case, binary operators are a common way to describe functions of two arguments because they are easy to read that way.
Ternary operators are more difficult to read, and they are correspondingly less common. But, since mathematical typography is not limited to a one-dimensional text string, many mathematical operators have large arity -- for instance, a definite integral arguably has 4 arguments (start, end, integrand, and differential).
To answer your second question: no, this does not circumvent the need for limits; you could just as easily say that the alternative was 42 instead of infinity.
I will also mention that your 1/x example doesn't really match the programming usage of the ?: ternary operator anyway. Note that 1/x is not a boolean; it looks like you're trying to use ?: to handle an exception-like condition, which would be better suited to a try/catch form.
Also, when you say "This assumes that x is a positive float", how is a reader supposed to know this? You may recall that there is mathematical notation that solves this specific problem by indicating limits from above....