This is a follow up to this previously asked question about the documentation function, which apparently deserved its own post.
Is there a way to dynamically get the docstring of either a function/macro OR a method in SBCL?
So far (documentation function-name 'function) gets me the docstring for regular functions (and I assume macros as well), but not methods.
I tried 'method, 'standard-method and even 't but they don't seem to work.
My problem is that the environment I work with (in a visual programming interface based on Lisp) is filled with little engines that can be either functions or methods and I don't know how to differentiate them. I just need users to be able to get the docstring quickly for any given symbol (or tool) in the library, no matter its type, if it exists of course.
Thanks !
Julien
Symbols name functions, including macros and generic-functions, but not methods. In order to uniquely identify a method, you need to know the generic-function and all the applicable modifiers and specializers.
For example, PRINT-OBJECT names a generic function, but is not sufficient to refer to a specific methods. You can however iterate over all methods specializing a generic function and manipulate their documentation: instead of passing a name to DOCUMENTATION, you give the function object and T. In order to do this portably, use closer-mop:
(ql:quickload :closer-mop)
For example:
(lambda (generic-function)
(map 'list
(lambda (method) (documentation method t))
(closer-mop:generic-function-methods generic-function)))
=> #<FUNCTION (LAMBDA (GENERIC-FUNCTION)) {1001BBCD3B}>
Let's try it:
CL-USER> (funcall * #'documentation)
(NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL)
Oops.
CL-USER> (defmethod documentation ((test (eql :test)) _)
"Test documentation"
"Returned value")
...
CL-USER> (documentation :test t)
"Returned value"
CL-USER> (funcall *** #'documentation)
("Test documentation" NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL)
Related
In swift you can unwrap optional values with a guard statement
guard let foo = foo else { return nil }
Is this statement making a copy of foo? In other words, could this statement be potentially expensive if foo is very large?
Actually this depends on type of foo e.x class type won't create a copy unlike struct type
guard isn't a magic keyword it simply if not presented in 1 word
guard let foo = foo else { return nil }
Could this statement be potentially expensive if foo is very large?
Instead of asking yourself the question that way, ask it this way: what if you had said
if foo != nil {
let foo = foo!
// everything else here
}
Was saying foo! to unwrap the Optional "expensive"? Whatever your answer is, it must be exactly the same for guard let foo = foo, because they both do exactly the same thing: they test for nil and, if safe, they unwrap the Optional. And that is all they both do. The one is merely syntactic sugar for the other.
You have two ways:
1- To only check if this foo does not equal nil
In this case you can check if foo is nil or not
if foo != nil {
// do you work here
}
2- To get information from foo
In this case, you have to unwrap this optional (with guard-let or if-let statements) and here we have two cases:
- if foo is a class, then it’s a reference type. so there will be no copy and a reference to this instance is created
- if foo is a struct, then it’s a value type. so an entirely new instance is created (copied from the original)
Also you can read this answer to see should you choose struct or class in swift
If the property you're unwrapping is a reference type (e.g. a class) then no it will not make a copy, it will just create a new property with a reference to the original instance.
If the property you're unwrapping is a value type (e.g. struct) then it will make a copy.
This question already has answers here:
Explicitly unwrapping optional nil does not cause crash
(2 answers)
Swift 3 incorrect string interpolation with implicitly unwrapped Optionals
(1 answer)
Closed 3 years ago.
I have an implicitly unwrapped optional with value nil.
Why does it print nil and not crash?
var x : Int!
print(x) // nil
That does not crash because print accepts Any as the first parameter. Are implicitly unwrapped optionals a kind of Any? Yes they are! Anything is Any. There is no need to unwrap the optional. An implicitly unwrapped optional can be used in a place where Any is expected without unwrapping the optional.
That could potentially be confusing because now you have something with type Any, which doesn't look like it's optional, but it is an optional under the hood. To avoid this, Swift will output a warning telling you that you are implicitly coercing whatever optional type to Any.
You need to use ! to force unwrap it here:
print(x!)
The reason why it's not crashing is because you are not force-unwrapping it in print(x). It will only crash one you try to force-unwrap it like print(x!)
IUO(Implicitly Unwrapped Optionals) are just special type of Optionals which will be automatically unwrapped one you use it inside chaining (say optional chaining), otherwise they remain Optionals.
Consider an example:
var implicitlyUO: Int!
implictlyUO = 4
print(implicitlyUO) // prints Optional(4)
print(implicitlyUO.advanced(by: 3)) // prints 7
implicitlyUO = nil
print(implicitlyUO) // prints nil
print(implicitlyUO.advanced(by: 3)) // Here it will crash as now it will be unwrapped and found it nil
var someNilValue:Int?
someNilValue = 4
print(someNilValue) // prints Optional(4)
print(someNilValue?.advanced(by: 3)) // prints Optional(7)
someNilValue = nil
print(someNilValue) // prints nil
print(someNilValue?.advanced(by: 3)) // prints nil
print(someNilValue!.advanced(by: 3)) /* Will crash here as we are force unwrapping nil which is the same case as implicitlyUO */
The only advantage you get with IUO is that you don't need ! (or explicitly unwrapping) in your code unnecessarily but you need to make sure that it is not nil.
I have a switch statement in Swift like this:
switch tuple {
case (let someObject, let current, nil):
return true
// Other cases...
}
The tuple is of type (SomeObject?, SomeObject, SomeObject?), and what I'm saying in English is: Match the case where the first two elements are not nil, while the third (an Optional) is nil.
Xcode 7 is telling me that since I didn't use the bindings someObject and current, I should replace it with an underscore. But if I replaced the first element in the tuple with an underscore, wouldn't it also match the cases where the first element is nil, because _ means the compiler ignores the value? I have a separate case for situations where the first element is nil.
For the record, it looks like my code still works as I expect it to, but I want to be sure and I can't find any documentation on this anywhere.
The underscore matches any value (nil or non-nil), but that is also
the case for your pattern:
case (let someObject, let current, nil):
where the first let someObject matches any value (nil or non-nil). So this does actually not work as you intended.
The optional type is defined as an enumeration:
enum Optional<T> : ... {
case None
case Some(T)
// ....
}
and nil is the same as Optional.None.
Therefore you can use
case (.Some, _, nil):
// Alternatively:
case (.Some, _, .None):
to match the case where the first element is not nil and the last
element is nil. The middle element of (SomeObject?, SomeObject, SomeObject?) is not an optional so it cannot be nil.
As of Swift 2 / Xcode 7, the x? pattern can be used as a synonym
for .Some(x), in your case
case (_?, _, nil):
matches the case where the first element is not nil and the last element is nil.
Hi I want ask a question about interface is nil
//i think err should be a interface (*MyError, nil)
var err error = (*MyError)(nil)
fmt.Println(reflect.TypeOf(err))
fmt.Println(reflect.ValueOf(err))`
the result told me interface value is not nil
result :
*main.MyError
<*main.MyError Value>
it's equivalent to interface (*main.MyError, <*main.MyError Value>)
why the interface value is not nil?
thanks
These two things are completely different:
The nil interface value. It does not hold an underlying type or value.
A non-nil interface value, which holds an underlying type and value, and that underlying value is nil in that underlying type (if it's one of the types that have a value called nil -- pointer, slice, map, channel, or function). Note that different types' nils are different and unrelated (pointer-nil and map-nil are unrelated); and some types don't have a value called nil.
You have a nil pointer (*MyError type), and you assign that to an interface variable (first of interface type error, then converted to interface type interface{} which is the parameter type of reflect.TypeOf() and reflect.ValueOf()). Therefore, those functions receive a non-nil interface value containing an underlying type *MyError and underlying value nil.
reflect.TypeOf(err) gets the underlying type, which is *MyError. And reflect.ValueOf(err) constructs a reflect.Value object representing the underlying type and value. This is what you see.
The stringification of a reflect.Value produces the string <T value>, where T is the type, but it doesn't try to stringily the value (nil pointer in this case). If you wanted to print the underlying value, perhaps you should have just done fmt.Println(err) instead.
http://golang.org/pkg/reflect/#ValueOf
ValueOf returns a new Value initialized to the concrete value stored
in the interface i. ValueOf(nil) returns the zero Value.
Why does the following not work in Swift?
if someObject === nil {
}
You have to do the test using the == operator such as
if someObject == nil {
}
I was thinking that === was more like making sure the instances where the exact same (basically comparing the pointers) and == was more like an isEqual check. Thus I would think === would be more appropriate for testing against nil, but I am obviously incorrect.
The documentation states:
=== or “Identical to” means that two constants or variables of class type
refer to exactly the same class instance.
== or “Equal to” means that two instances are considered “equal” or “equivalent”
in value, for some appropriate meaning of “equal”, as defined by the type’s designer.”
It works exactly like you expect:
var s: String? = nil
s === nil // true
The only caveat is that to compare to nil, your variable must able to be nil. This means that it must be an optional, denoted with a ?.
var s: String is not allowed to be nil, so would therefore always returns false when === compared to nil.
My first instinct would be that nil is not a class instance, but a reference. So someObject cannot be an equivalent class instance to nil.