Testing user-set variable for equality in ELisp - elisp

I am new to Emacs Lisp and changing some code in mu4e-send-delay. I want to test whether the user set a variable to a value, e.g. in the scratch buffer:
(setq mu4e-sent-messages-behavior 'delete)
delete
These three tests return false:
(eq 'mu4e-sent-messages-behavior 'delete)
nil
(equal 'mu4e-sent-messages-behavior 'delete)
nil
(equal 'mu4e-sent-messages-behavior "delete")
nil
And this one returns true, but with the member function for lists:
(if (member mu4e-sent-messages-behavior '(delete)) t nil)
t
If the user keeps the setting at the default set in the code:
(defcustom mu4e-sent-messages-behavior 'sent
...
)
then member also fails:
(when (member mu4e-sent-messages-behavior '(sent)) t nil)
nil
What is wrong with my tests, and how can I test for the value of a variable set by the user?

Don't quote the variable name when passing it to eq:
(eq mu4e-sent-messages-behavior 'delete)
The problem with this piece of code:
(when (member mu4e-sent-messages-behavior '(sent)) t nil)
is that when will either return nil (if the condition is false) or the last value of the body (if the condition is true), which in this case is nil - so this piece of code will always return nil. Use if instead of when, and you should see it returning t.

Related

Wrong type argument: stringp, nil with org-map-entries

I've encountered an error which I can't resolve. I have a file test.org which simply contains a first level headline: * test
(with-temp-buffer
(insert-file-contents "~/test.org")
(goto-char (point-min))
(org-map-entries
(lambda ()
(compare-strings
"* test\n" nil nil
(thing-at-point 'line t) nil nil
t))
"LEVEL=1"))
This returns Wrong type argument: stringp, nil. The org-map-entries function works normally, but there seems to be a problem when it is used with with-temp-buffer.
The temp buffer is in fundamental mode and nothing you do in your code changes that. OTOH, the org- functions assume that the buffer is in Org mode and (sometimes) barf if that is not the case.
Try this:
(with-temp-buffer
(org-mode)
(insert-file-contents "~/test.org")
(goto-char (point-min))
(org-map-entries
(lambda ()
(compare-strings
"* test\n" nil nil
(thing-at-point 'line t) nil nil
t))
"LEVEL=1"))

The find-lisp-object-file-name return wrong value

I'm using Emacs 26.1, and recently I found the find-lisp-object-file-name always return nil when I call it in following ways:
(find-lisp-object-file-name 'call-process nil)
;;=> nil
(find-lisp-object-file-name 'call-process 'defun)
;;=> nil
However, when I use the describe-function to show information about call-process, it shows the call-process is from "C source code". It looks like the function find-lisp-object-file-name is not reliable.
More examples:
(find-lisp-object-file-name 'cond nil)
;;=> nil *WRONG*
(find-lisp-object-file-name 'cdr nil)
;;=> nil *WRONG*
(find-lisp-object-file-name 'user-full-name nil)
;;=> "src/editfns.c" *CORRECT*
The question: how can I always get the correct file name information of a symbol?

When does reflect.IsValid return false?

I am curious about IsValid function, because during my use of this function, it never returned false. So when does it return a negative result?
As the doc reflect.IsValid() says:
It returns false if v is the zero Value. [...]
Most functions and methods never return an invalid value. If one does, its documentation states the conditions explicitly.
Value.IsValid() is supposed to report whether the reflect.Value itself is valid, not the value it wraps (if any).
All the examples below print false. You can try them on the Go Playground.
The simplest example is calling IsValid() on the zero value of reflect.Value (which is a struct):
fmt.Println(reflect.Value{}.IsValid())
The 2nd simplest example is when passing nil to reflect.ValueOf():
fmt.Println(reflect.ValueOf(nil).IsValid())
Another example: start with a pointer being nil, in this case there is no "pointed" value, a nil pointer points to nowhere. Attempting to get the reflect.Value of the pointed value using Value.Elem() results in a zero reflect.Value whose IsValid() method will return false:
var i *int
v := reflect.ValueOf(i)
v2 := v.Elem()
fmt.Println(v2.IsValid())
Or in one line:
fmt.Println(reflect.ValueOf((*int)(nil)).Elem().IsValid())
Same thing if you call Value.Indirect() on the above reflect.Value():
fmt.Println(reflect.Indirect(v).IsValid())
Or attempting to get a non-existing struct field by name using Value.FieldByName():
s := struct{}{}
fmt.Println(reflect.ValueOf(s).FieldByName("").IsValid())
Or attempting to get a non-existing method by name using Value.MethodByName():
fmt.Println(reflect.ValueOf(s).MethodByName("").IsValid())
Or attempting to get a value from a map by a non-existing key using Value.MapIndex():
m := map[int]int{}
fmt.Println(reflect.ValueOf(m).MapIndex(reflect.ValueOf(3)).IsValid())
The list goes on...

Weird nil / not-nil behavior

I have the following code in my project:
mod := srt.PrimaryModule()
if mod != nil {
mods[mod.Name()] = mod
}
When it executes, I get:
PANIC: runtime error: invalid memory address or nil pointer dereference
with the stack right at the third line of that. (Yes it's the mod dereference, the map mods is created just a line above...)
So, when is a nil value not equal to nil? And why?
srt.PrimaryModule()
returns an interface type, Module, with a Name() method defined returning string.
In this particular case, srt is typed StdReflectedType, which is an interface type with a function PrimaryModule() returning type Module. The actual implementation of srt is a struct that returns an uninitialized Module value from its fields.
Further, if I do
reflect.ValueOf(mod)
the result is the zero reflect.Value.
From the reflect package documentation:
ValueOf returns a new Value initialized to the concrete value stored in the interface i. ValueOf(nil) returns the zero Value
Which seems right, except the previous line just determined mod != nil. So what gives?
I cannot seem to reproduce this in a minimal example - is there any sensible behavior that could cause those lines to do this - am I not understandig something important about interface values and nil pointers?
if any concrete value has been stored in the interface, the interface will not be nil. However, the concrete value stored in the interface can be a nil pointer.
For example, is the fmt.Println(mod) output, the concrete value, nil?
if mod != nil {
fmt.Println(mod)
mods[mod.Name()] = mod
}
Does srt.PrimaryModule() return a nil pointer to mod? If so, mod.Name() will panic with a nil pointer dereference.
References:
The Go Programming Language Specification: Interface types
Go Data Structures: Interfaces
Why is my nil error value not equal to nil?
What is the output from this revised version of your code?
mod := srt.PrimaryModule()
if mod != nil {
fmt.Printf("%T %v\n", mod, mod)
if mod.(Module) != nil {
fmt.Println(mod.Name())
mods[mod.Name()] = mod
}
}

A 'Rosetta Stone' for Swift's optional types?

I grasp (I think) the basics of optional types in Swift and roughy understand the difference between ? and !, but I'm still mystified by some of the results I get when I use these features — in particular the role of Some <T>, and how it differs from <T> itself; some of the specific error messages I get in certain cases; and how Some <T> seems to pop up in cases where I expect <T>.
But I also feel like even when I understand individual cases, my grasp of the picture gets away from me, and I feel like there is a code here that I could decipher if only I completely understood one simple example — a Rosetta Stone, if you will — for !, ?, optional values, and unpacking.
Here, for example, is a simple and (I think) exhaustive catalog of the basic cases:
class Foo {
var one:String = "";
var two:String?
var three:String!
}
let test = Foo() // {one "" nil nil}
test.one
//test.one? // ERROR: ? requires optional type
//test.one! // ERROR: ! requires optional type
// ?, unassigned
test.two // nil
test.two? // nil
//test.two! // ERROR: EXEC_BAD_INSTRUCTION
test.two == nil // true
test.two? == nil // true
//test.two! == nil // ERROR: Cannot invoke == with an argument list of type (#lvalue String, NilLiteralConvertable)
//test.two.isEmpty // ERROR: String? does not have .isEmpty
test.two?.isEmpty // nil
//test.two!.isEmpty // ERROR: EXEC_BAD_INSTRUCTION
// !, unassigned
test.three // nil
test.three? // nil
//test.three! // ERROR: EXEC_BAD_INSTRUCTION
test.three == nil // true
test.three? == nil // true
//test.three! == nil // ERROR: Cannot invoke == with an argument list of type (#lvalue String, NilLiteralConvertable)
//test.three.isEmpty // ERROR: EXEC_BAD_INSTRUCTION
test.three?.isEmpty // nil
//test.three!.isEmpty // ERROR: EXEC_BAD_INSTRUCTION
test.two = "???" // {one "" {Some "???"} nil}
test.three = "!!!" // {one "" {Some "???"} three "!!!"}
// ?, assigned
test.two // {Some "???"}
test.two? // {Some "???"}
test.two! // "???"
test.two == nil // false
test.two? == nil // false
//test.two! == nil // ERROR: Cannot invoke == with an argument list of type (#lvalue String, NilLiteralConvertable)
//test.two.isEmpty // ERROR: String? does not have .isEmpty
test.two?.isEmpty // {Some false}
test.two!.isEmpty // false
// !, assigned
test.three // "!!!"
test.three? // {Some "!!!"}
test.three! // "!!!"
test.three == nil // false
test.three? == nil // false
//test.three! == nil // ERROR: Cannot invoke == with an argument list of type (#lvalue String, NilLiteralConvertable)
test.three.isEmpty // false
test.three?.isEmpty // {Some false}
test.three!.isEmpty // false
If someone could annotate this, explaining what's going on it each case, I think that answer could serve as a solid reference for how these features of Swift work.
Alright, I am going to try to answer this all. Might not have tie to get through everything:
NOTE: Feel free to call me out on errors. This took a while, so I surely made a few.
Quick note: Optional is actually an enum. It has two states: .None, and .Some(T), where T is the type of the value (in your case, String).
test.one
Foo has a property named one that returns an String. A definite String, not an optional, meaning that it will definitely have a value. You treat this similarly to how you would just write "HI!" in your code. The value of this is really ""
//test.one? // ERROR: ? requires optional type
This is an error because test.one, as said above, returns a definite String, and so there is no chance that it is nil. You can guarantee that the return value exists.
//test.one! // ERROR: ! requires optional type
Same as the ?. The ! is a forced unwrapping operator, meaning that there is a chance that test.one may be nil, but you want to force the value out anyway (or crash if it is not there). However, there is no chance it is nil, and so you cannot have a ? or a !.
test.two // nil
test.two is a String?, which can be nil. Because it is optional, you are allowed to return nil like you do in your code. The real value of this is .None, and so the value you are seeing is actually a String? not a String.
test.two? // nil
This basically does the same thing as the one above, except you are explicitly saying that the value possibly is nil.
//test.two! // ERROR: EXEC_BAD_INSTRUCTION
You can never use a ! on a nil value without expecting it to crash. When you use this operator, it forces a value out of it (so you would have a String, not String?). However, if the value is nil, there is no value to force out, so you end up crashing the program.
test.two == nil // true
test.two as is clear returns nil, or .None (they are equivalent). And so if you compare nil == nil or .None == .None, it is true.
test.two? == nil // true
Same as the one above.
//test.two! == nil // ERROR: Cannot invoke == with an argument list of type (#lvalue String, NilLiteralConvertable)
Force-unwrapping a nil value crashes the program, every time. It doesn't make sense, either, because force-unwrapping would return a String, not String?. String cannot be nil.
//test.two.isEmpty // ERROR: String? does not have .isEmpty
Basically, whenever you want to call a method on an optional, you need to make sure it has a value using either optional-binding or optional-chaining (two separate things). String? is equal to Optional.Some(String), and you need to get past the optional layer to get to the string you want.
test.two?.isEmpty // nil
Here you use optional-chaining. Basically, the way this works is that test.two is evaluated. If the value is .Some(String), then you call isEmpty on the string. Otherwise, if it is .None, then nothing happens. These optional chains can occur multiple lines per statement, such as test.two?.firstEmoji? (assuming such a method were implemented.
//test.two!.isEmpty // ERROR: EXEC_BAD_INSTRUCTION
Again, force-unwrapping a nil optional is bad. Don't do it without first checking that the value is indeed .Some.
test.three // nil
Since three is implicitly unwrapped, and it was initialized to nil (by not being set to something else), this shouldn't be surprising.
test.three? // nil
This is not something you are likely to use in real code since it's essentially optional chaining, but without anything after it. However here, since .three is implicitly unwrapped ? has the effect of "re-wrapping" it: the type of the result is now String?. This make little difference here, but see what it does below, after test.three has had a String value assigned.
//test.three! // ERROR: EXEC_BAD_INSTRUCTION
As above is not possible to unwrap nil. This may seem confusing since the declaration is often described as producing a variable that is "implicitly unwrapped"; but that should be read as "implicitly unwrapped if it is not nil".
test.three == nil // true
test.three? == nil // true
//test.three! == nil // ERROR: Cannot invoke == with an argument list of type (#lvalue String, NilLiteralConvertable)
Same as 2 above. If you have a force-unwrapped variable, a ? appears to un-force-unwrap it, which is a behavior I would not advise. Try to use force-unwrapped optionals infrequently, mostly having to do with parts of the UI if you really need to. Often times, it will crash when you don't expect it to.
//test.three.isEmpty // ERROR: EXEC_BAD_INSTRUCTION
test.three?.isEmpty // nil
//test.three!.isEmpty // ERROR: EXEC_BAD_INSTRUCTION
When an optional is not assigned, it defaults to nil. If you then try to force-unwrap it... I think you get the idea. The first and third lines try to call a method from String on nil (works in ObjC, not Swift). Second one uses optional chaining to check if it is nil before calling the method, which it can't because it know it is nil.
test.two = "???" // {one "" {Some "???"} nil}
test.three = "!!!" // {one "" {Some "???"} three "!!!"}
This sets test.two equal to .Some("???") and test.three equal to .Some("!!!") The output you see simply shows all the variables held in the class, and how they change.
test.two // {Some "???"}
test.two? // {Some "???"}
test.two! // "???"
test.two is now .Some("???"), so when you call it, that is what is returned: a String? with a value. When you force-unwrap it, it now returns the value held in .Some without crashing because there is indeed a String in it.
test.two == nil // false
test.two? == nil // false
test.two is still an optional, so in the first two, when it compares them to nil, it realizes, "Hey, there is .Some value, so it is not nil."
//test.two! == nil // ERROR: Cannot invoke == with an argument list of type (#lvalue String, NilLiteralConvertable)
Force-unwrapping a value turns the value of test.two from a String? to a String. Strings are never nil, because if they were, they would need to be optional. Comparing a value that is definitely a String to nil would make no sense, because you know for a fact that it is not nil; otherwise, the program would have crashed before!
//test.two.isEmpty // ERROR: String? does not have .isEmpty
test.two is a String?, not a String. In order to access the string itself, you need to make sure it is there to access, using either a ? or a !
test.two?.isEmpty // {Some false}
This says, "If test.two contains a String (not nil), then find if it is empty." It says {Some false} because you are accessing a member of an Optional still, not a direct String.
test.two!.isEmpty // false
!, on the other hand, does return a String. Calling .isEmpty on a String is either true or false, which in this case is false because you set it equal to a non-empty string.
test.three // "!!!"
test.three force-unwraps the String from it, which in this case works because it has a value.
test.three? // {Some "!!!"}
You treat this as a normal optional (not force-unwrapped), and so you get a Some(String) instead of just a String.
test.three! // "!!!"
Since you force-unwrapped it in its declaration, it is force-unwrapped here.
test.three == nil // false
This is another strange behavior, as it should probably be an error. It is supposed to be a String, which cannot be compared to nil, but something wacky is going on here. I will get back to you when I find out about this.
test.three? == nil // false
Treats test.three as a normal optional, and checks if its state is .None, or nil.
//test.three! == nil // ERROR: Cannot invoke == with an argument list of type (#lvalue String, NilLiteralConvertable)
What the one two above should be like. Can't compare a String to nil, so it throws an error.
test.three.isEmpty // false
Looks at the string value that was forced out (which exists; otherwise, it would have crashed). The string is not empty, so it is false.
test.three?.isEmpty // {Some false}
Treats it as a String?. If test.three is not nil, then it takes the value from .Some (a String), and evaluates if it is empty, which it is not.
test.three!.isEmpty // false
The String is forced out of the optional, and isEmpty is called directly to it. It is not empty, so it returns false.
I hope I helped clarify things, and I will let you know why that one case is the way it is when I find out for myself :]

Resources