How autoload works? [duplicate] - elisp

This question already has answers here:
What is the purpose of off-loading definitions with autoload in emacs? Why not autoloading is slow?
(3 answers)
Closed 6 years ago.
Assume I have 3 functions in a packages:
;;;###autoload
(defun my-funcA () ...)
;;;###autoload
(defun my-funcB () ...)
;;;###autoload
(defun my-func-init () ...)
If one of the functions is called, will all functions declaration be loaded?
Put it in another way, if my-func-init must be loaded in order to use this package, does it mean all the autoloads are redundant?

On their own, these comments are just comments.
A separate process is used to extract the associated definitions into a loaddefs.el file. When that file is loaded, all of those autoloads are defined. Thus all of the autoloads for a great many libraries can be bundled together into a single file, which is fast to load.
M-x elisp-index-search RET autoload cookie RET
A magic autoload comment (often called an "autoload cookie")
consists of ‘;;;###autoload’, on a line by itself, just before the
real definition of the function in its autoloadable source file.
The command ‘M-x update-file-autoloads’ writes a corresponding
‘autoload’ call into ‘loaddefs.el’. (The string that serves as the
autoload cookie and the name of the file generated by
‘update-file-autoloads’ can be changed from the above defaults, see
below.) Building Emacs loads ‘loaddefs.el’ and thus calls
‘autoload’. ‘M-x update-directory-autoloads’ is even more powerful;
it updates autoloads for all files in the current directory.
The package manager processes the autoload cookies for any given package, so package authors can simply add those comments as appropriate.

Related

Difference between load and include in Scheme R7RS

In Scheme R7RS there is both a load and include form.
Include is described as:
Semantics: Both include and include-ci take one or
more filenames expressed as string literals, apply an
implementation-specific algorithm to find corresponding files, read
the contents of the files in the specified order as if by repeated
applications of read, and effectively re- place the include or
include-ci expression with a begin expression containing what was read
from the files. The difference between the two is that include-ci
reads each file as if it began with the #!fold-case directive, while
include does not. Note: Implementations are encouraged to search for
files in the directory which contains the including file, and to
provide a way for users to specify other directories to search.
Load is described as:
An implementation-dependent operation is used to trans- form filename
into the name of an existing file con- taining Scheme source code. The
load procedure reads expressions and definitions from the file and
evalu- ates them sequentially in the environment specified by
environment-specifier. If environment-specifier is omitted,
(interaction-environment) is assumed. It is unspecified whether the
results of the expres- sions are printed. The load procedure does not
af- fect the values returned by current-input-port and
current-output-port. It returns an unspecified value. Rationale: For
portability, load must operate on source files. Its operation on other
kinds of files necessarily varies among implementations.
What is the rationale for the two forms? I assume it is historic. Is there any import semantic difference between the two forms? I see that load can optionally include an environment specifier and include doesn't have that. And include-ci has no direct equivalent using load. But comparing load and include alone, what is the difference and is it important?
I think the critical difference is that include is syntax (or in traditional Lisp terms, it is a macro) while load is a function. In traditional Lisp terms (there will be a much more formal definition of this in Scheme terms which I am not competent to give) this means that include does its work at macro-expansion time, while load does its work at evaluation time. These times can be very different for an implementation which has a file compiler: macro-expansion time happens during compilation of files, while evaluation happens only much later, when the compiled files are loaded.
So, if we consider two files, f1.scm containing
(define foo 1)
(include "f2.scm")
and f2.scm containing
(define bar 2)
then if you load, or compile f1.scm it is exactly the same as if you had loaded or compiled a file fe.scm which contained:
(define foo 1)
(begin
(define bar 2))
which in turn is the same as if fe.scm contained:
(define foo 1)
(define bar 2)
In particular this inclusion of the files happens at macro-expansion time, which happens when the compiler runs: the object file (fasl file) produced by the compiler will include compiled definitions of foo and bar, and will not in any way depend on f2.scm or its compiled equivalent existing.
Now consider f3.scm containing:
(define foo 1)
(load "f2")
(note I have assumed that (load "f2") (as opposed to (load "f2.scm")) loads the compiled file if it can find it, and the source file if it can't: I think this is implementation-dependent).
Loading the source of this file will do the same thing as loading f1.scm: it will cause foo and bar to be defined. But compiling this file will not: it will produce a compiled file which, when it is later loaded will try to load either the source or compiled versions of f2.scm. If that file exists, at load time, then it will be loaded and the effect will be the same as the include case. If it does not exist at load time, bad things will happen. Compiling f1.scm will not cause the definitions in f2.scm to be compiled.
Depending on your background it might be worth comparing this to, say, C-family languages. What include does is what #include does: it splices in source files as they are read, and in C (as in many Scheme/Lisp systems) this happens as the files are compiled. What load does is to load code at runtime, which, in C, you would need to do by invoking the dynamic linker or something.
Historically, Lisp implementations did not offer module systems.
Large programs used load in order to run a set of instructions, the load function runs a REPL script by reading S-expressions from a file, one by one, and passing them to eval.
Include, on the other hand, is used to inline the code read from a file into the your code. It does not evaluate the code.
...replace the include or include-ci expression with a begin expression containing what was read from the files
The added 'begin' prepares the code read from the file to be evaluated sequentially.
Sources: Question quotes ,Racket docs

Global go-flag AddCommand clarification and/or example

In my early days of learning Go and trying to use package github.com/jessevdk/go-flags. I checked the Fly example referenced in another go-flags thread, but it apparently does not use AddCommand (at least per my grep).
The godoc article recommends defining a global parser instance and to implement each command in a separate file. Each of those command files should define a go init function which calls AddCommand on the global parser.
Making my parser global was easy enough. Confused on the init() setups:
1) My understanding is that init() order execution is random, other than your main's init running last.
2) If so, I can't ensure that my NewParser() call in my configuration code has been called prior my AddCommand() calls.
3) My code compiles, but a --help doesn't show any defined commands, making me think that indeed, the AddCommand() was called before the NewParser()
/* Just a guess */
4) QED I'm confused!
Does anybody have a recommended example I could go learn from?

Use vs Import vs Require vs Require-extension in Chicken Scheme

I'm a little hazy on the differences between (use) and (import) in Chicken. Similarly, how do (load), (require) and (require-extension) differ?
These things don't seem to be mentioned much on the website.
Load and require are purely run-time, procedural actions. Load accepts a string argument and loads the file with that name (which can be source or compiled code) into the running Scheme, so that whatever it defines becomes available. Require does the same thing, but checks if the file has already been loaded by seeing if provide has been called on the same name (typically by the file as it is loaded). They are relatively rare in Scheme programming, corresponding to plug-ins in other languages, where code unknown at compile time needs to be loaded. See the manual page for unit eval for more details.
Import is concerned with modules rather than files. It looks for the named module, which must have already been loaded (but see below for Chicken 5), and makes the names exported from that module visible in the current context. In order to successfully import a module, there must be an import library for it. It is syntax, so the module name must appear explicitly in the call and cannot be computed at run time. See the manual page on modules for more details.
Require-library does the Right Thing to load code. If the code is already part of the running Scheme, either because it is built into Chicken, it does nothing. Otherwise it will load a core library unit if there is one, or will call require as a last resort. At compile time, it does analogous things to make sure that the environment will be correct at run time. See the "Non-standard macros and special forms" page in the manual for more details.
Use does a require-library followed by an import on the same name. It is the most common way to add functionality to your Chicken program. However, we write (import scheme) and (import chicken) because the functionality of these modules is already loaded. Require-extension is an exact synonym for use, provided for SRFI 55 compatibility. In R7RS mode, import is also a synonym for use.
Update for Chicken 5
Use has been removed from the language, and import now does what use used to do: it loads (if necessary) and then imports. Require-extension is consequently now a synonym for import.
In addition, Chicken-specific procedures and macros have been broken into modules with names like (chicken base) and (chicken bitwise).

uncalled variables [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am trying to get started with Lisp and I have some (messy) code that i want to be able to ask the user for a title and url.
Save them in a variable, and then print them out when called. I am running into troubles though. First of all i don't know how to compile my program to run it. Also, the one time when i did run it i got an error about the variable title being uncalled. Can anyone help me with either of these things? Sorry i can't give you more information about the error.
;;Define a function called make-cd that takes four parameters
(defun make-url( title url ))
(list :title title :url url)
;;In the make-url function create a plist that takes the passed values
;; Define global variable db and set its value to nil
(defvar *db* nil)
;; Define a function that takes one paramter and pushes it to the make-url func.
;;(defun add-url (url) (push url *db*))
;; Define a function that takes the *db* variable and makes the output pretty
(defun dump-db ()
(dolist (url *db*)
(format t "~{~a:~10t~a~%~}~%" url)))
(defun prompt-read (prompt)
(format *query-io* "~a: " prompt)
(force-output *query-io*)
(read-line *query-io*))
Perhaps this will help.
Lisp programs aren't always distributed in compiled form. Having your program as just the source code is even better then only having the FASL (that's how Lisp binaries are called) because it makes it easier to fix problems if they are found later.
Traditionally, more complex programs, are arranged by means of ASDF package asdf:defsystem macro. You can read more about it here: http://common-lisp.net/~mmommer/asdf-howto.shtml . You can find examples on the internet, of how this is usually done through using Quicklisp and looking into its ~/quicklisp/dists/quicklisp/software/<name of the program>/ directory to see how other programs are arranged.
Once system is defined by asdf:defsystem, you would use asdf:oos to "operate" on it, that is load it. However, Quicklisp has become a very popular and easy to use utility for working with Lisp systems (it uses ASDF package underneath too). So, considering you have it, you would then (ql:quickload "your-system").
In order to make your system available locally through Quicklisp, I'd recommend doing it this way: In your $HOME directory (on Linux it is usually aliased with tilde ~) in the file: ~/.config/common-lisp/source-registry.conf (you may need to create one, if it's not there already), add something like:
(:source-registry
(:tree (:home "quicklisp/quicklisp/"))
(:tree (:home "Projects/my-project/"))
:inherit-configuration)
The above would imply that ~/Projects/my-project/ directory contains a system definition file (*.asd), where you have described what files belong to the system and instructed on how to load them etc.
For other options for adding local projects, read the Quicklisp FAQ
For more information about source-registry.conf file format read ASDF manual.
This is a bit involved at the beginning, so I'd advise you to just install one project using Quicklisp and study how it is made. Alexandria could be a good start - besides being a generally useful package, it isn't very large and illustrates the matter very well, IMO.
The code you have provided contains errors and will not compile. The error is in your definition of make-url. The proper definition should be:
(defun make-url( title url )
(list :title title :url url))
Notice the difference in parenthesis placements.
In your code you had an additional parenthesis following the parameter list. This closed the defun, causing make-url to be evaluated as a function with no body. The next line was then evaluated as a call to the built-in function list. The arguments were evaluated, and an error was encountered when it attempted to find a value for title. There is no binding in the global environment, a binding for title only exists within the body of make-url.
Also, your definition of add-url is commented out. A semi-colon begins a comment in Lisp.
How to compile and run your program depends on what compiler you are using. If you are using SBCL the function is sb-ext:save-lisp-and-die. A simple program like this would usually be run in a Read-Eval-Print-Loop(REPL), and most compilers will enter one when started. If you have SBCL installed you can start a repl by entering the command 'SBCL' to the command prompt. If your code is in an external file you can then load that using Load.

Including files from within racket/scheme

I'm trying to use drracket to work thru the exercises in "How To
Design Programs 2nd Ed".
A number of the exercises in this build up on the answers to previous
questions, so I would like to include the source files from the
answered questions so that I don't have to copy and paste the the body
of the old answer each time.
My main question is: How do I do this?
I have looked thru the documentation and found a method called
include that seems to do what I want, but I cant work out how to use
it correctly.
eg - I have two files:
test.rkt - this compiles and runs fine and contains one function:
(define (test) 1)
(test)
newtest.rkt - I would like this file to to be able to use the function defined in test.rkt.
(require racket/include)
(include "test.rkt")
(define (newtest) (* test 2))
When I try to compile this I get the following error:
module: this function is not defined
(Not very informative, but that's all the information I'm given...)
How do I get this first file to include without getting this error? Is include
even the right function for this, or is my approach completely wrong?
The include form isn't working because when the language is set to "Beginning Student" or one of the other teaching languages, DrRacket actually wraps your program in a module. You can see this if you open "test.rkt" in a regular text editor. The #reader.... bit is what generates the module. But when that gets included into the other file, it doesn't make sense. Thus the error complaining about module.
Unfortunately, as far as I can tell, the HtDP languages still don't have provide, which is what you need to make this work right.
If you really want to get this working, here's a way to hack around it:
Create a new file called "provide.rkt" in the same directory as your other files. While you're editing this file (and only this file), set the Language in DrRacket to "Determine language from source". Put the following two lines in "provide.rkt":
#lang racket
(provide provide)
(That declares a module using the full Racket language that provides only the built-in special form provide.)
Add the following lines to your "test.rkt" program. (Make sure DrRacket's Language is set back to "Beginning Student" or whichever teaching language you're using for this.)
(require "provide.rkt")
(provide test)
Now "test.rkt" is a module that exports your test function. (It was always a module, it just didn't have any exports before, so it wasn't very useful.)
Add the following lines to your "newtest.rkt" program:
(require "test.rkt")
That imports everything provided by "test.rkt": currently just test, but you can add other things to, you just have to provide them.

Resources