285 karma · joined January 14, 2017
1. Telling apart optional arguments to a function that weren't given from arguments that were given and were NIL. Typically giving a default value for the argument is sufficient to avoid the problem, but you can also add an extra parameter that tells whether the argument was given.
(defun foo (&optional (x :default-value xp))
;; X holds the argument given by the caller, or the keyword
;; :DEFAULT-VALUE if nothing was given.
;; XP is T if the argument was given, or NIL if it was not given.
)
2. Finding an item that may be NIL. Functions such as GETHASH (which looks up a key in a hash table) usually allow you to specify a default value, and they will return a second value to indicate whether something was found. ;; Increment the value of KEY in TABLE, or if the key doesn't
;; exist, use 10 as a default, increment that and set the
;; result to the table.
(incf (gethash key table 10))
(multiple-value-bind (value existsp) (gethash key table)
;; VALUE holds the value if it exists, or NIL if it doesn't.
;; EXISTSP is T if the key exists, or NIL if it doesn't.
)
Notice that in CL additional return values can be ignored if you're not interested in them, so you only need to use MULTIPLE-VALUE-BIND when you actually need it. You could also wrap it in a trivial macro if you're using it a lot. (defmacro if-some-let ((var form) &body (then &optional else))
(let ((somep (gensym "SOMEP")))
`(multiple-value-bind (,var ,somep) ,form
(if ,somep ,then ,else))))
(if-some-let (val (gethash key table))
(format t "Found: ~a~%" val)
(format t "Didn't find.~%"))Finnish (/ Swedish) keyboards have ¤ on `<Shift> 4` ($ is `<Alt Gr> 4`).
Lisp does have block comments,
#| This is a block comment |#
You can also use feature expressions to effectively comment out code #+(or)
(defun foo ...)
The reader will skip over the following sexp if the feature expression isn't true (and `(or)` never is).That sounds like what we call "räntä" in Finland, which, according to Wikipedia, is called "sleet" in Commonwealth countries.
[1]: https://en.wikipedia.org/wiki/Rain_and_snow_mixed#Terminolog...
[1]: http://orgmode.org/worg/dev/org-syntax.html#Affiliated_keywo...
No, it wouldn't. `+` is a valid list bullet in Org-mode. For strikethrough, the plus-signs must be attached to the start and end of the words (`+an example+`).
~ $ rlwrap sbcl --noinform
CL-USER> (defun foobar (x y)
(if (evenp x)
(/ x y)
(* x y)))
FOOBAR
CL-USER> (foobar 10 0)
debugger invoked on a DIVISION-BY-ZERO in thread
#<THREAD "main thread" RUNNING {1001BB64C3}>:
arithmetic error DIVISION-BY-ZERO signalled
Operation was /, operands (10 0).
Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [ABORT] Exit debugger, returning to top level.
(SB-KERNEL::INTEGER-/-INTEGER 10 0)
0] backtrace 3
Backtrace for: #<SB-THREAD:THREAD "main thread" RUNNING {1001BB64C3}>
0: (SB-KERNEL::INTEGER-/-INTEGER 10 0)
1: (FOOBAR 10 0)
2: (SB-INT:SIMPLE-EVAL-IN-LEXENV (FOOBAR 10 0) #<NULL-LEXENV>)
0] down
(FOOBAR 10 0)
1] source 1
(IF (EVENP X)
(#:***HERE*** (/ X Y))
(* X Y))
1] (defun foobar (x y)
(if (and (evenp x) (not (zerop y)))
(/ x y)
(* x y)))
WARNING: redefining COMMON-LISP-USER::FOOBAR in DEFUN
FOOBAR
1] restart-frame
0[1]: Only one major Finnish city (Viipuri) was occupied by the USSR (after the civilian population of the city was evacuated).
In this case you would use
(setf (vref chip x y) new-value)
to call the function (just like with AREF above). Using SETF has the advantage that you can define "modify macros" that read and write a place. For example, (incf (vref chip x y) delta)
would increment the place by DELTA. Or (rotatef (vref chip x1 y1)
(vref chip x2 y2))
would swap two pixels.[1]: You can ask the Lisp to drop all debug information as an optimization, which makes development impractical, but still possible. Some implementation might allow you to distribute a program without the compiler, but the standard does not specify that.
They are. That's the whole point. If someone comes to try and convince you of their point, you can either listen and engage in a discussion, or if you believe that isn't going to work out, you can refuse. Both are valid options and necessary at times.
Likewise if you want to convince someone of your point and they refuse to listen to you, you can either change your approach so that they do, or declare them a lost cause and move on. Both are again valid options and necessary at times.
The problem is when you keep trying the approach that the other person doesn't want to listen to. That will just alienate them further, and can easily turn into harassment.
(loop :for i :below 5
:when (evenp i) :collect i)
;=> (0 2 4)Basically I just add the properties URL and BROWSER to any entry I want to be a bookmark. I have the numpad key 4 bound to a command that opens the url (works either in the org file buffer itself, or from an agenda view). I also have the numpad key 1 bound to an agenda search for the tag :bm: (searching for a property is too slow), so I can easily get a list of all bookmarks, which can then be filtered by tags, category, top-level headline and regexes.
sb-ext:*evaluator-mode*
to :INTERPRET to enable it. CL-USER> (ql:quickload :trivia)
... loads ...
CL-USER> (asdf:test-system :trivia)
... test output ...
But unfortunately not all libraries set up their test-ops properly. You can usually find a readme at ~/quicklisp/dists/quicklisp/software/... which might have instructions for running tests. M-x replace-regexp word1\(.*\)word2$ RET word3\1word4 RET
Assuming you have `replace-regexp` bound to a key, it's practically the same. Works on the whole buffer (by default), or the region (if selected). (defgeneric xplusone (x)
(:method (x) (+ 1 x)))
Also, generic functions are slower than regular functions (due to dynamic dispatch), so using them for type optimization would be rather counterproductive.There no need to hunt for todos; use `C-c \` (or `C-c /` for more options) to create a sparse tree. It supports the same queries as agenda tag searches. For example, `/!` to show all unfinished tasks, or `/TODO` for just the ones with TODO as the keyword.
You can also use the timeline view with a prefix argument to see tasks in the current file (`C-u C-c a L`). Or you can restrict other agenda views to the current buffer (`C-c a < t` for a task list). Custom agenda commands can also specify their own set of agenda files (they can also be chosen by a function whenever the agenda view is created).