Suppose I have to define a function called foo. Suppose that, in order to define it, I use some auxiliary functions foo1, foo2, foo3, ...
When I load the file containing those functions, from the top-level I can use all of them. Instead I want to "see" from the top-level only the function foo and "hide" the others. How can I achieve this result?
You can use flet.
E.g.,
(flet ((foo1 (...) ...)
(foo2 (...) ...)
(foo3 (...) ...))
(defun foo (...)
(foo1 (foo2 (foo3 ...))))
(defun goo (...)
(foo2 (foo1 (foo3 ...)))))
Related
I'm confuse about the symbols now, I tried:
CL-USER> (defclass foo2 () ())
#<STANDARD-CLASS COMMON-LISP-USER::FOO2>
CL-USER> (describe 'foo2)
COMMON-LISP-USER::FOO2
[symbol]
FOO2 names the standard-class #<STANDARD-CLASS COMMON-LISP-USER::FOO2>:
Direct superclasses: STANDARD-OBJECT
No subclasses.
Not yet finalized.
No direct slots.
; No value
CL-USER> (find-symbol "foo2")
NIL
NIL
Why I can't found the "foo2" symbol with the find-symbol function?
What I want do with this:
CL-USER> (defun my-make-instance (name n) (make-instance (make-symbol (format nil "~a-~a" name n)))
MY-MAKE-INSTANCE
CL-USER> (my-make-instance "foo" 2)
; Evaluation aborted on #<SB-PCL:CLASS-NOT-FOUND-ERROR foo2 {1003A3A003}>.
And I get:
There is no class named #:|foo2|.
how to I do this?
And other case:
CL-USER> (describe 'foo2)
COMMON-LISP-USER::FOO2
[symbol]
FOO2 names the standard-class #<STANDARD-CLASS COMMON-LISP-USER::FOO2>:
Direct superclasses: STANDARD-OBJECT
No subclasses.
Not yet finalized.
No direct slots.
; No value
CL-USER> (describe (intern "foo2"))
COMMON-LISP-USER::|foo2|
[symbol]
; No value
Why it happened? Is the "foo2" create by defclass a internal symbol, isn't?
Common Lisp is case sensitive and the reader is case converting; your source code generally gets converted to upper case when it is read by the compiler / interpreter. The symbol named "foo2" does not exist in your example, but the symbol named "FOO2" does.
The call to make-symbol will return a new symbol object, not the symbol object associated with your class.
The easiest way to fix your code would be to replace your make-symbol call in my-make-instance with a call to read-from-string to get the same case converting reader behavior to be used on your argument string. The reader will then also intern the symbol in the current package, ensuring it is the same symbol object as the one associated with your class. You also probably want to use defun instead of defmacro to define my-make-instance in this case.
In short you probably want the following code:
(defun my-make-instance (name n)
(make-instance (read-from-string (format nil "~a-~a" name n))))
(defclass foo-2 () ())
(my-make-instance "foo" 2)
;returns below instance
#<FOO-2 {100AB67443}>
If you describe the symbol and get
FOO2 names the standard-class #<STANDARD-CLASS COMMON-LISP-USER::FOO2>:
then FOO2 in uppercase characters really indicates that the symbol has an uppercase name.
* 'foo2
FOO2
Now you can use the function symbol-name to get the name of a symbol as a string:
* (symbol-name 'foo2)
"FOO2"
As you can see above, the name is uppercase.
Using the uppercase name to find the symbol then works:
* (find-symbol "FOO2")
FOO2
:INTERNAL
I have added the following method to the generic function speak but would now like to remove this particular method in the REPL without removing the rest of the generic functions' methods.
(defmethod speak :around ((c courtier) string) ; [1]
(format t "Does the King believe that ~A?" string)
(if (eql (read) 'yes)
(if (next-method-p) (call-next-method)) ; [2]
(format t "Indeed, it is a preposterous idea.~%"))
'bow)
[1] The :around method replaces the primary method for the type.
[2] Then it decides whether to call the primary method or not.
The documentation link to the function remove-method has no examples and I don't know what is the syntax to refer to the actual :around method above.
(remove-method #'speak)
TOO FEW ARGUMENTS
(remove-method #'speak :around)
NO-APPLICABLE-METHOD
From the documentation:
remove-method generic-function method
It expects a generic function object and a method object as arguments.
One can find the method via find-method.
CL-USER 39 > (find-method #'speak
(list :around)
(list (find-class 'courtier) (find-class t)))
#<STANDARD-METHOD SPEAK (:AROUND) (COURTIER T) 42001285EB>
CL-USER 40 > (remove-method #'speak
(find-method #'speak
(list :around)
(list (find-class 'courtier)
(find-class t))))
#<STANDARD-GENERIC-FUNCTION SPEAK 422000A68C>
Note also that a good Lisp development environment may also allow to remove methods in the editor or the inspector.
Note that in the Lisp listener, one does not need to call find-method twice like above. The variable * contains the last result.
CL-USER 43 > (find-method #'speak
(list :around)
(list (find-class 'courtier)
(find-class t)))
#<STANDARD-METHOD SPEAK (:AROUND) (COURTIER T) 4200150DEB>
CL-USER 44 > (remove-method #'speak *)
#<STANDARD-GENERIC-FUNCTION SPEAK 422000A68C>
Here is another interaction example using SLIME in GNU Emacs with the presentation feature for SLIME enabled. A presentation is Lisp output, which keeps the connection between the printed object and the generated text.
Call the find-method function. It returns the method. Here we use presentations, which keep the connections between text and Lisp objects. The output is displayed in the color red and it is mouse-sensitive. Moving the mouse over the red returned object will add interaction options.
Now type (remove-method #'speak and then middle-click (or whatever SLIME is configured to use) on the red output: the presentation (the text and the connected object) will be copied to the line. Type ) and enter the form. SLIME has actually constructed a list with the real object and not the textual representation, then.
This is how repls work on the Symbolics Lisp Machine and in CLIM / McCLIM...
If using GNU Emacs with SLIME, you can also use slime-inspector. For example define generic function foo and two methods:
USER> (defgeneric foo (x))
#<STANDARD-GENERIC-FUNCTION FOO (0)>
USER> (defmethod foo ((x string)) (length x))
#<STANDARD-METHOD FOO (STRING) {100B4D7E23}>
USER> (defmethod foo ((x integer)) x)
#<STANDARD-METHOD FOO (INTEGER) {100C355843}>
You have two main options to enter the inspector:
From the REPL, type #'foo so that a presentation object for the generic method is printed:
USER> #'foo
#<STANDARD-GENERIC-FUNCTION FOO (0)>
Either right-click the presentation (anywhere inside #<...>) and select Inspect, or put the cursor in the presentation and press C-c C-v TAB (slime-inspect-presentation-at-point).
From a source file, enter slime-inspect, a.k.a. C-c I, and enter #'foo.
In both cases, you are shown a view similar to this:
#<STANDARD-GENERIC-FUNCTION {505A9A2B}>
--------------------
Name: FOO
Arguments: (X)
Method class: #<STANDARD-CLASS COMMON-LISP:STANDARD-METHOD>
Method combination: #<SB-PCL::STANDARD-METHOD-COMBINATION STANDARD () {1000214003}>
Methods:
(INTEGER) [remove method]
(STRING) [remove method]
(....)
Each [remove method] text is actually a button, click or press Return on any of them to remove the associated method from the generic function.
Test #1
I have a globally declared variable f, and a function with argument named f:
(defvar f 1)
(defun test (f)
f)
I call the function and it returns the value of the argument:
(test 2)
=> 2
Test #2
I again have a globally declared variable f, and a function with argument named f. This time, however, the function returns a lambda, which returns f:
(defvar f 1)
(defun test (f)
#'(lambda ()
f))
I call the function and it returns the lambda function. Then I call the lambda function and it returns the value of the global f:
(funcall (test 2))
=> 1
I am surprised. I thought the lambda function is a closure and would return the local f, not the global f. How do I modify the test function and/or the lambda function so that the lambda function returns the local f, not the global f?
A pointer to an online resource that discusses this particular scoping issue would be appreciated.
By using defvar you are declaring f a special (aka dynamically bound) variable. f in your code from there on are no longer lexically closed but in fact the same as the global variable momentarily changed to 2.
Because of this feature lispers are not happy about global variables without their *earmuffs*. Once they have *earmuffs* it's much easier to see it:
(defvar *f* 1) ; special variable *f*
(defun test (*f*) ; momentarily rebind *f*
(format nil "*f* is ~a~%" *f*) ; use new value
#'(lambda () ; return lambda using *f*
*f*)) ; *f* goes back to being 1
(funcall (test 2)) ; ==> 1 (prints "*f* is 2\n")
So the lesson is: Never make global variables without *earmuffs* since you will get crazy runtime errors which are almost impossible to detect. This naming convention isn't just for fashion!
As for documentation the hyperspec actually shows how dynamic variables work in the examples for defparameter and defvar. See that they call (foo) => (P V) and that foo re-binds *p* and *v* during its call to bar and, since they are dynamically bound, bar uses the altered values.
Is there any introspective magic that would give me a list of functions defined in a module?
module Foo
function foo()
"foo"
end
function bar()
"bar"
end
end
Some mythical function like:
functions_in(Foo)
Which would return: [foo,bar]
The problem here is that both names and whos list exported names from a module. If you wanted to see them then you would need to do something like this:
module Foo
export foo, bar
function foo()
"foo"
end
function bar()
"bar"
end
end # module
At this point both names and whos would list everything.
If you happen to be working at the REPL and for whatever reason did not want to export any names, you could inspect the contents of a module interactively by typing Foo.[TAB]. See an example from this session:
julia> module Foo
function foo()
"foo"
end
function bar()
"bar"
end
end
julia> using Foo
julia> whos(Foo)
Foo Module
julia> names(Foo)
1-element Array{Symbol,1}:
:Foo
julia> Foo.
bar eval foo
Somehow the tab completion is looking up un-exported names, so there must be a way to get Julia to tell them to you. I just don't know what that function is.
EDIT
I did a little digging. The un-exported function Base.REPLCompletions.completions seems to work, as demonstrated in a continuation of the REPL session we were previously using:
julia> function functions_in(m::Module)
s = string(m)
out = Base.REPLCompletions.completions(s * ".", length(s)+1)
# every module has a function named `eval` that is not defined by
# the user. Let's filter that out
return filter(x-> x != "eval", out[1])
end
functions_in (generic function with 1 method)
julia> whos(Foo)
Foo Module
julia> names(Foo)
1-element Array{Symbol,1}:
:Foo
julia> functions_in(Foo)
2-element Array{UTF8String,1}:
"bar"
"foo"
I've got a recursive function (scavenged from github):
(defn delete-recursively [fname]
(let [func (fn [func f]
(when (.isDirectory f)
(doseq [f2 (.listFiles f)]
(func func f2)))
(clojure.java.io/delete-file f))]
(func func (clojure.java.io/file fname))))
I can't figure out this func thing. I need help :)
Why is it possible to use the same symbol func for
the name the function is bound to,
the name of an argument in the fn form,
the called function and
the first parameter of the call?
Or is something else going on?
Written from my phone so I apologize.
This function seems needlessly obfuscated.
"func"is a function that delete normal files if given a file and apply a function "f" passed as parameter to all files in a directory if given a directory.
Now "func"is given to "func" as "f" parameter so it does its job recursively.
Easy :3