I have an alist in the following form:
((|* bank accounts| (|account 1| |account 2|))
(|* airline miles| (|account 1| |account 2|))
.....
.....)
I don't how to use assoc to access the symbols, since they're framed on both sides with "|".
Quoted symbols are treated like any other symbol, but the string case of the symbol is preserved:
(assoc '|foo bar| '((|baz| . 1) (|foo bar| . 2))) => (|foo bar| . 2)
Here are some more examples (with standard reader case settings):
(intern "foo bar") => |foo bar|
(intern "Foo") => |Foo|
(intern "FOO") => FOO
A longer answer can be found on cliki. Please also refer to 2.3.4 Symbols as Tokens in the Common Lisp Hyperspec.
The same way they are printed:
> (defparameter *alist*
'((|* bank accounts| |account 1| |account 2|)
(|* airline miles| |account 1| |account 2|)))
*ALIST*
> (cdr (assoc '|* bank accounts| *alist*))
(|account 1| |account 2|)
> (cdr (assoc '|* airline miles| *alist*))
(|account 1| |account 2|)
The vertical-bars are just multiple escape characters allowing the use of characters which the standard reader wouldn't read as a symbol. For example, whitespace would result in separate symbols in standard reader syntax:
> (read-from-string "foo bar")
FOO ;
4
Numbers won't yield a symbol:
> (read-from-string "123 456")
123 ;
4
> (type-of *)
(INTEGER 0 16777215)
Without escaping, and the default readtable-case, the read symbols would be in upper case:
> 'foo
FOO
But:
> (intern "1234")
|1234| ;
NIL
> (type-of *)
SYMBOL
> '|foo bar baz|
|foo bar baz|
> (symbol-name *)
"foo bar baz"
Related
I want to enumerate the list of all environment variables available in my Lisp process. I want the same list that is returned by the C variable environ.
Neither SBCL nor Clozure CL seem to provide it out of the box. Can I do it using CFFI?
Interfacing with the OS and common lisp is still quite dependent on your lisp distribution. So more or less is not easy to find a good library that works in all CL distributions.
I recommend you to work with UIOP, which comes with ASDF 3 and above and it is the best library for working with the OS inside common lisp nowadays. However it doesn't have a function to list the environment variables, furthermother if we take a look at how it works with environment varables we can see that for every lisp distribution we have a different version of accessing the variables only for example:
(defun getenv (x)
"Query the environment, as in C getenv.
Beware: may return empty string if a variable is present but empty;
use getenvp to return NIL in such a case."
(declare (ignorable x))
#+(or abcl clasp clisp ecl xcl) (ext:getenv x)
#+allegro (sys:getenv x)
#+clozure (ccl:getenv x)
#+cmucl (unix:unix-getenv x)
#+scl (cdr (assoc x ext:*environment-list* :test #'string=))
#+cormanlisp
(let* ((buffer (ct:malloc 1))
(cname (ct:lisp-string-to-c-string x))
(needed-size (win:getenvironmentvariable cname buffer 0))
(buffer1 (ct:malloc (1+ needed-size))))
(prog1 (if (zerop (win:getenvironmentvariable cname buffer1 needed-size))
nil
(ct:c-string-to-lisp-string buffer1))
(ct:free buffer)
(ct:free buffer1)))
#+gcl (system:getenv x)
#+genera nil
#+lispworks (lispworks:environment-variable x)
#+mcl (ccl:with-cstrs ((name x))
(let ((value (_getenv name)))
(unless (ccl:%null-ptr-p value)
(ccl:%get-cstring value))))
#+mkcl (#.(or (find-symbol* 'getenv :si nil) (find-symbol* 'getenv :mk-ext nil)) x)
#+sbcl (sb-ext:posix-getenv x)
#-(or abcl allegro clasp clisp clozure cmucl cormanlisp ecl gcl genera lispworks mcl mkcl sbcl scl xcl)
(not-implemented-error 'getenv))
(defsetf getenv (x) (val)
"Set an environment variable."
(declare (ignorable x val))
#+allegro `(setf (sys:getenv ,x) ,val)
#+clisp `(system::setenv ,x ,val)
#+clozure `(ccl:setenv ,x ,val)
#+cmucl `(unix:unix-setenv ,x ,val 1)
#+ecl `(ext:setenv ,x ,val)
#+lispworks `(hcl:setenv ,x ,val)
#+mkcl `(mkcl:setenv ,x ,val)
#+sbcl `(progn (require :sb-posix) (symbol-call :sb-posix :setenv ,x ,val 1))
#-(or allegro clisp clozure cmucl ecl lispworks mkcl sbcl)
'(not-implemented-error '(setf getenv))
so for getting one variable:
CL-USER> (uiop:getenv "GEM_PATH")
"/Users/toni/.rvm/gems/ruby-2.1.6#afs-dev:/Users/toni/.rvm/gems/ruby-2.1.6#global"
as pointed in a comment if you are usign SBCL you can get this with it:
SB-EXT:POSIX-ENVIRON
example in c:
extern char **environ;
//...
int i = 0;
while(environ[i]) {
printf("%s\n", environ[i++]); // prints in form of "variable=value"
}
| GEM_HOME=/Users/toni/.rvm/gems/ruby-2.1.6#afs-dev |
| SHELL=/bin/bash |
| TERM=dumb |
| TMPDIR=/var/folders/zs/t9wnzpqj2bdgjjgjwb8pqxc80000gn/T/ |
| Apple_PubSub_Socket_Render=/private/tmp/com.apple.launchd.e0K30SfWTc/Render |
| USER=toni |
| SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.KvlUaU8PD5/Listeners |
| __CF_USER_TEXT_ENCODING=0x1F5:0x0:0x8 |
| PATH=/Users/toni/.rvm/gems/ruby-2.1.6#afs-dev/bin:/Users/toni/.rvm/gems/ruby-2.1.6#global/bin:/Users/toni/.rvm/rubies/ruby-2.1.6/bin/:/usr/texbin:/Library/TeX/texbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/toni/.rvm/bin |
| PWD=/Users/toni/learn/lisp/cl-l/stackoverflow/scripts |
| LANG=es_ES.UTF-8 |
| XPC_FLAGS=0x0 |
| XPC_SERVICE_NAME=org.gnu.Emacs.13016 |
| SHLVL=1 |
| HOME=/Users/toni |
| BUNDLE_PATH=/Users/toni/.rvm/gems/ruby-2.1.6#afs-dev |
| LOGNAME=toni |
| GEM_PATH=/Users/toni/.rvm/gems/ruby-2.1.6#afs-dev:/Users/toni/.rvm/gems/ruby-2.1.6#global |
| DISPLAY=/private/tmp/com.apple.launchd.ljkiChb2wE/org.macosforge.xquartz:0 |
| _=/tmp/babel-6131RLH/C-bin-6131T_s |
example in SBCL
(sb-ext:posix-environ)
("TERM=dumb" "TERMCAP=" "COLUMNS=139" "INSIDE_EMACS=25.2.1,comint"
"BUNDLE_PATH=/Users/toni/.rvm/gems/ruby-2.1.6#afs-dev"
"GEM_PATH=/Users/toni/.rvm/gems/ruby-2.1.6#afs-dev:/Users/toni/.rvm/gems/ruby-2.1.6#global"
"GEM_HOME=/Users/toni/.rvm/gems/ruby-2.1.6#afs-dev" "LANG=es_ES.UTF-8"
"XPC_FLAGS=0x0" "USER=toni" "XPC_SERVICE_NAME=org.gnu.Emacs.13016"
"DISPLAY=/private/tmp/com.apple.launchd.ljkiChb2wE/org.macosforge.xquartz:0"
"LOGNAME=toni"
"PATH=/Users/toni/.rvm/gems/ruby-2.1.6#afs-dev/bin:/Users/toni/.rvm/gems/ruby-2.1.6#global/bin:/Users/toni/.rvm/rubies/ruby-2.1.6/bin/:/usr/texbin:/Library/TeX/texbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/toni/.rvm/bin"
"SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.KvlUaU8PD5/Listeners"
"Apple_PubSub_Socket_Render=/private/tmp/com.apple.launchd.e0K30SfWTc/Render"
"SHELL=/bin/bash" "HOME=/Users/toni" "__CF_USER_TEXT_ENCODING=0x1F5:0x0:0x8"
"TMPDIR=/var/folders/zs/t9wnzpqj2bdgjjgjwb8pqxc80000gn/T/"
"SBCL_HOME=/Users/toni/.roswell/impls/x86-64/darwin/sbcl/1.3.16/lib/sbcl"
"ROS_OPTS=((\"program\"\"(:eval\\\"(ros:quicklisp)\\\")\")(\"lispdir\"\"/usr/local/Cellar/roswell/17.4.8.76/etc/roswell/\")(\"verbose\"\"0\")(\"homedir\"\"/Users/toni/.roswell/\")(\"wargv0\"\"/usr/local/bin/ros\")(\"argv0\"\"/usr/local/bin/ros\")(\"quicklisp\"\"/Users/toni/.roswell/lisp/quicklisp/\")(\"impl\"\"sbcl/1.3.16\")(\"dynamic-space-size\"\"3gb\")(\"sbcl.version\"\"1.3.16\")(\"allegro.version\"\"100express\")(\"ccl-bin.version\"\"1.11\")(\"ecl.version\"\"16.1.3\")(\"slime.version\"\"2017.02.27\")(\"sbcl-bin.version\"\"1.2.11\")(\"default.lisp\"\"sbcl\"))")
So for other implementations you mut investigate how to,
Finally exist a good library called OSICAT that:
OSICAT is a lightweight operating system interface for Common Lisp on
Unix-platforms. It is not a POSIX-style API, but rather a simple lispy
accompaniment to the standard ANSI facilities.
so in your case you must use:
(osicat:environment)
(("TERM" . "dumb") ("TERMCAP" . "") ("COLUMNS" . "139") ("INSIDE_EMACS" . "25.2.1,comint") ("BUNDLE_PATH" . "/Users/toni/.rvm/gems/ruby-2.1.6#afs-dev") ("GEM_PATH" . "/Users/toni/.rvm/gems/ruby-2.1.6#afs-dev:/Users/toni/.rvm/gems/ruby-2.1.6#global") ("GEM_HOME" . "/Users/toni/.rvm/gems/ruby-2.1.6#afs-dev") ("LANG" . "es_ES.UTF-8") ("XPC_FLAGS" . "0x0") ("USER" . "toni") ("XPC_SERVICE_NAME" . "org.gnu.Emacs.13016") ("DISPLAY" . "/private/tmp/com.apple.launchd.ljkiChb2wE/org.macosforge.xquartz:0") ("LOGNAME" . "toni") ("PATH" . "/Users/toni/.rvm/gems/ruby-2.1.6#afs-dev/bin:/Users/toni/.rvm/gems/ruby-2.1.6#global/bin:/Users/toni/.rvm/rubies/ruby-2.1.6/bin/:/usr/texbin:/Library/TeX/texbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/toni/.rvm/bin") ("SSH_AUTH_SOCK" . "/private/tmp/com.apple.launchd.KvlUaU8PD5/Listeners") ("Apple_PubSub_Socket_Render" . "/private/tmp/com.apple.launchd.e0K30SfWTc/Render") ("SHELL" . "/bin/bash") ("HOME" . "/Users/toni") ("__CF_USER_TEXT_ENCODING" . "0x1F5:0x0:0x8") ("TMPDIR" . "/var/folders/zs/t9wnzpqj2bdgjjgjwb8pqxc80000gn/T/") ("ROS_OPTS" . "((\"program\"\"(:eval\\\"(ros:quicklisp)\\\")\")(\"lispdir\"\"/usr/local/Cellar/roswell/17.4.8.76/etc/roswell/\")(\"verbose\"\"0\")(\"homedir\"\"/Users/toni/.roswell/\")(\"wargv0\"\"/usr/local/bin/ros\")(\"argv0\"\"/usr/local/bin/ros\")(\"quicklisp\"\"/Users/toni/.roswell/lisp/quicklisp/\")(\"impl\"\"ccl-bin/1.11\")(\"dynamic-space-size\"\"3gb\")(\"sbcl.version\"\"1.3.16\")(\"allegro.version\"\"100express\")(\"ccl-bin.version\"\"1.11\")(\"ecl.version\"\"16.1.3\")(\"slime.version\"\"2017.02.27\")(\"sbcl-bin.version\"\"1.2.11\")(\"default.lisp\"\"ccl-bin\"))"))
SO I hope that this should work
Racket represents XML data as an X-expression: http://docs.racket-lang.org/xml/index.html?q=#(def._((lib._xml/private/xexpr-core..rkt)._xexpr~3f))
which is defined as follows:
xexpr = string
| (list symbol (list (list symbol string) ...) xexpr ...)
| (cons symbol (list xexpr ...))
| symbol
| valid-char?
| cdata
| misc
In the second alternative, why is it (list symbol string) and not (cons symbol string) ? Is there any specific reason to use list instead of cons ? If not, would there be any advantage in using cons instead of list ?
It's really just a preference on the part of the X-expression designers, probably to mirror let's syntax (which also uses proper lists only).
With (list symbol string), you'd represent Stack Overflow as:
(a ((href "http://stackoverflow.com/")) "Stack Overflow")
whereas with (cons symbol string), it'd be:
(a ((href . "http://stackoverflow.com/")) "Stack Overflow")
Some would consider the "dot" an ugly thing to see.
Is there a way to configure org-mode spreadsheets to show thousand separators? I would like 1000 to be shown as 1,000.
Here is a solution. First define the function group-number:
(defun group-number (num &optional size char)
"Format NUM as string grouped to SIZE with CHAR."
;; Based on code for `math-group-float' in calc-ext.el
(let* ((size (or size 3))
(char (or char ","))
(str (if (stringp num)
num
(number-to-string num)))
;; omitting any trailing non-digit chars
;; NOTE: Calc supports BASE up to 36 (26 letters and 10 digits ;)
(pt (or (string-match "[^0-9a-zA-Z]" str) (length str))))
(while (> pt size)
(setq str (concat (substring str 0 (- pt size))
char
(substring str (- pt size)))
pt (- pt size)))
str))
from: Emacs Cookbook - put commas in numbers
Next, use it in your formula:
| | | |
|-----------+-------+-------------|
| 2000 | 3100 | 5,100 |
| 11 | 22 | 33 |
| 111221212 | 29996 | 111,251,208 |
| | | 0 |
#+TBLFM: $3='(group-number (+ $1 $2));N
Here we are using the group-number function to format the result of an emacs lisp form - rather than using the calc formula syntax.
I would like to be able to specify the window layout of the Emacs when starting it from commandline.
More specifically, I invoke "emacs file1 file2 file3 file4" and would, for example, like see
+---------+ +--------+
| file1 | | buff |
| | | list |
+---------+ instead of the default +--------+ that I see currently
| | | |
| file3 | | file4 |
+---------+ +--------+
My emacs is GNU Emacs 24.0.91.1, and I do not use emacsclient.
Note, I do not want to make the change permanent. That is why I ask for command-line solution.
Put the following in layout.el
(setq inhibit-startup-screen t)
(defun ordered-window-list-aux (tree)
(if (windowp tree)
(list tree)
(append (ordered-window-list-aux (nth 2 tree))
(ordered-window-list-aux (nth 3 tree)))))
(defun ordered-window-list ()
"Lists windows from top to bottom, left to right."
(ordered-window-list-aux
(car (window-tree))))
(require 'cl)
(defun fill-windows ()
"Make window list display recent buffer."
(mapcar*
(lambda (win buf)
(set-window-buffer win buf))
(nreverse (ordered-window-list))
(buffer-list)))
(delete-other-windows)
;; your window configuration
(split-window-horizontally)
(split-window-vertically)
;; Make window list display recent buffer
(fill-windows)
Then
emacs blah foo bar --load layout.el
The only thing you have to do is customizing the layout the way you want using a combination of the following functions:
(split-window-horizontally)
(split-window-vertically)
(other-windows 1)
I was reading subr.el and saw this code:
(defalias 'backward-delete-char 'delete-backward-char)
(defalias 'search-forward-regexp (symbol-function 're-search-forward))
Interestingly, the first line doesn't use symbol-function while the second line does. The only difference I know of these two ways of using defalias is that the help for backward-delete-char (the first one) displays that it is an alias for delete-backward-char while the help for search-forward-regexp doesn't.
Is there a case when the second way is better than the first way?
The two defalias usages are slightly different. The first links the function cell for 'backward-delete-char to that of 'delete-backward-char. The second links the 'search-forward-regexp to the function that is currently called by 're-search-forward.
The difference is that if you later change the definition of 'delete-backward-char, 'backward-delete-char will now have the new behavior. Whereas in the second case, changing the function for 're-search-forward has no effect on the behavior of 'search-forward-regexp.
Perhaps some ascii art can help:
+-------------------------+ +-----------------+
|#<subr re-search-forward>| <-- |re-search-forward|
+-------------------------+ +-----------------+
^ +---------------------+
\------ |search-forward-regexp|
+---------------------+
+----------------------------+ +--------------------+ +--------------------+
|#<subr delete-backward-char>| <-- |delete-backward-char| <-- |backward-delete-char|
+----------------------------+ +--------------------+ +--------------------+
This documentation might help clear things up.
Well, it really is not the same thing... Here is a little game I just played:
(defun a () (message "hello"))
a
(a)
"hello"
(defalias 'b (symbol-function 'a))
(lambda nil (message "hello"))
(defalias 'c 'a)
a
(b)
"hello"
(c)
"hello"
(defun a () (message "howdy"))
a
(a)
"howdy"
(b)
"hello"
(c)
"howdy" ' c changed meaning, b did not...