Clojure function to print symbol name and symbol value - clojure

I have been struggling to find an answer or develop a solution. I am trying to figure out how to make code that makes code in Clojure. For my first feat, I want a function that will print to stdout the name of the symbol and its value, useful for debugging. Example:
(def mysymbol 5)
(debugging-function mysymbol)
mysymbol: 5
Does that make sense? Thanks for your help.
Post Discussion Update
Here is the answer from #amalloy:
(defmacro ?
"A useful debugging tool when you can't figure out what's going on:
wrap a form with ?, and the form will be printed alongside
its result. The result will still be passed along."
[val]
`(let [x# ~val]
(prn '~val '~'is x#)
x#))
So:
(? myvariable)

You can see a simple version of this that I wrote on github. The main point is that you can't do this with a function, but with a macro it's simple enough - you just have to get your quoting and unquoting right.

Related

Emacs Lisp and non-deterministic regexes

I've been spending too much time lately trying to debug some auto-complete-mode functionality in Emacs, this function appears to be non-deterministic and has left me utterly confused.
(re-search-backward "\\(\\sw\\|\\s_\\|\\s\\.\\|\\s\\\\|[##|]\\)\\=")
The command is called in a while loop, searching backwards from the current point to find the full "word" that should be autocompleted. For reference, the actual code.
A bit of background and my investigations
I have been trying to setup autocompletion for Javascript, using slime to connect to a Node.js backend.
Autocomplete inside a Slime REPL connected to a Node.js backend is perfect,
Autocomplete inside a js2-mode buffer, connected to Slime, is failing to look up completions from slime. In this image you can see it falling back to the words already in the buffer.
I've tracked this down to Slime's slime-beginning-of-symbol function.
Assume that I'm trying to complete fs.ch where fs has been required and is in scope already, the point is located on after the h character.
In the slime repl buffer the beginning function moves the point all of the way back until it hits whitespace and matches fs.ch.
In the js2-mode buffer the beginning function moves the point only to the dot character and matches only ch.
Reproducing the problem
I've been testing this by evaling (re-search-backward "\\(\\sw\\|\\s_\\|\\s\\.\\|\\s\\\\|[##|]\\)\\=") repeatedly in various buffers. For all examples, the point starts at the end of the line and moves backwards until the search fails.
In the scratch buffer fs.ch the point ends on the c.
In the slime repl fs.ch the point ends on the f.
In the js2-mode buffer fs.ch the point ends on the c.
In an emacs-lisp-mode buffer fs.ch the point ends on the f.
I have no idea why this is happening
I'm going to assume that there's something in these modes that either sets or unsets a global regex var that then has this effect, but so far I've been unable to find or implicate anything.
I even tracked this down to the emacs c code, but at that point realised that I was in completely over my head and decided to ask for help.
Help?
You should replace \\s\\. with \\s. in your regexp.
I "fixed" the problem by redefining the source that gets added to auto complete's ac-sources.
I'm still learning my way around elisp so this is likely the most hack-like way of achieving what I need, but it works.
I changed the regex from:
\\(\\sw\\|\\s_\\|\\s\\.\\|\\s\\\\|[##|]\\)\\=
to
\\(\\sw\\|\\s_\\|\\s.\\|\\s\\\\|[##|]\\)\\=
(note the change of \\s\\.\\ to \\s.\\).
And then overrode the auto-complete setup in my init.el. (I'll probably find a hundred ways to refine this when I actually know elisp).
(defun js-slime-beginning-of-symbol ()
"Move to the beginning of the CL-style symbol at point."
(while (re-search-backward "\\(\\sw\\|\\s_\\|\\s.\\|\\s\\\\|[##|]\\)\\="
(when (> (point) 2000) (- (point) 2000))
t))
(re-search-forward "\\=#[-+.<|]" nil t)
(when (and (looking-at "#") (eq (char-before) ?\,))
(forward-char)))
(defun js-slime-symbol-start-pos ()
"Return the starting position of the symbol under point.
The result is unspecified if there isn't a symbol under the point."
(save-excursion (js-slime-beginning-of-symbol) (point)))
(defvar ac-js-source-slime-simple
'((init . ac-slime-init)
(candidates . ac-source-slime-simple-candidates)
(candidate-face . ac-slime-menu-face)
(selection-face . ac-slime-selection-face)
(prefix . js-slime-symbol-start-pos)
(symbol . "l")
(document . ac-slime-documentation)
(match . ac-source-slime-case-correcting-completions))
"Source for slime completion.")
(defun set-up-slime-js-ac (&optional fuzzy)
"Add an optionally-fuzzy slime completion source to `ac-sources'."
(interactive)
(add-to-list 'ac-sources ac-js-source-slime-simple))
In response to my own question about regex global state. There is a lot of it.
Emacs regexes use syntax tables defined in the major mode to determine which characters to match. The reason I was seeing the dot match in the lisp mode but not the js mode was because of different definitions. In the lisp mode '.' is defined as symbol, in js2-mode '.' is defined as punctuation.
As a consequence, an alternative way to fix the problem is to redefine .'s syntax in js2-mode. I tried this out and redefined . as a word with (modify-syntax-entry ?. "w"). However I decided not to stay with that result because it will probably break something down the line.
Also, I have to thank the people in #emacs, they really helped me out on this, teaching me about syntax tables and the horrors of elisp regex globals.

How do I beautify lisp source code?

My code is a mess many long lines in this language like the following
(defn check-if-installed[x] (:exit(sh "sh" "-c" (str "command -v " x " >/dev/null 2>&1 || { echo >&2 \"\"; exit 1; }"))))
or
(def Open-Action (action :handler (fn [e] (choose-file :type :open :selection-mode :files-only :dir ListDir :success-fn (fn [fc file](setup-list file)))) :name "Open" :key "menu O" :tip "Open spelling list"))
which is terrible. I would like to format it like so
(if (= a something)
(if (= b otherthing)
(foo)))
How can I beautify the source code in a better way?
The real answer hinges on whether you're willing to insert the newlines yourself. Many systems
can indent the lines for you in an idiomatic way, once you've broken it up into lines.
If you don't want to insert them manually, Racket provides a "pretty-print" that does some of what you want:
#lang racket
(require racket/pretty)
(parameterize ([pretty-print-columns 20])
(pretty-print '(b aosentuh onethunoteh (nte huna) oehnatoe unathoe)))
==>
'(b
aosentuh
onethunoteh
(nte huna)
oehnatoe
unathoe)
... but I'd be the first to admit that inserting newlines in the right places is hard, because
the choice of line breaks has a lot to do with how you want people to read your code.
I use Clojure.pprint often for making generated code more palatable to humans.
it works well for reporting thought it is targeted at producing text. The formatting built into the clojure-mode emacs package produces very nicely formatted Clojure if you put the newlines in your self.
Now you can do it with Srefactor package.
Some demos:
Formatting whole buffer demo in Emacs Lisp (applicable in Common Lisp as well).
Transform between one line <--> Multiline demo
Available Commands:
srefactor-lisp-format-buffer: format whole buffer
srefactor-lisp-format-defun: format current defun cursor is in
srefactor-lisp-format-sexp: format the current sexp cursor is in.
srefactor-lisp-one-line: turn the current sexp of the same level into one line; with prefix argument, recursively turn all inner sexps into one line.
Scheme variants are not as polished as Emacs Lisp and Common Lisp yet but work for simple and small sexp. If there is any problem, please submit an issue report and I will be happy to fix it.

What is the difference between ; and ;; in Clojure code comments?

What is the difference between ; and ;; when starting a comment in Clojure? I see that my text editor colours them differently, so I'm assuming there is notionally some difference.
I also see that Marginalia treats them differently:
; Stripped entirely
;; Appears in text section of marginalia
(defn foobar []
; Appears in code section of marginalia output
;; Again, appears in code section of marginalia output
6)
There is no difference as far as the interpreter is concerned. Think of ; ;; ;;; and ;;;; as different heading levels.
Here is my personal use convention:
;;;; Top-of-file level comments, such as a description of the whole file/module/namespace
;;; Documentation for major code sections (i.e. groups of functions) within the file.
;; Documentation for single functions that extends beyond the doc string (e.g. an explanation of the algorithm within the function)
; In-line comments possibly on a single line, and possibly tailing a line of code
Check out the official description of the meaning of ; vs ;; in elisp: since the Clojure indenter is basically the same, it will treat them similarly. Basically, use ; if you are writing a long sentence/description "in the margins" that will span multiple lines but should be considered a single entity. Their example is:
(setq base-version-list ; there was a base
(assoc (substring fn 0 start-vn) ; version to which
file-version-assoc-list)) ; this looks like
; a subversion
The indenter will make sure those stay lined up next to each other. If, instead, you want to make several unrelated single-line comments next to each other, use ;;.
(let [x 99 ;; as per ticket #425
y "test"] ;; remember to test this
(str x y)) ;; TODO actually write this function
Emacs ; to be used for end-of-line comments and will indent in surprising ways if that is not your intent. ;; does not so I usually use ;;.
Clojure doesn't care - any line is ignored from the ; to EOL.
I believe there is a tradition in CL of using increasing numbers of ; to indicate more important comments/sections.
no meaning for the language. ; is a reader macro for comment
perhaps other tools parse them but "within clojure" they are the same.
There is no difference from a Clojure-perspective. I find that ;; stands out a little better than ;, but that's only my opinion.
Marginalia on the other hand treats them differently because there are times when a comment should remain in the code section (e.g. license) and those are flagged with ;. This is an arbitrary decision and may change in the future.
In emacs lisp modes including clojure-mode, ;; is formatted with the convention of being at the beginning of a line, and indented as as any other line, based on the context. ; is expected to be used at the end of a line, so emacs will not do what you want it to if you put a single-semicolon comment at the beginning of a line expecting it to tab to the indentation for the present context.
Example:
(let [foo 1]
;; a comment
foo) ; a comment
I'm not sure (not used Clojure and never heard of this before), but this thread might help.

in emacs-lisp, how do I correctly use replace-regexp-in-string?

Given a string, I want to replace all links within it with the link's description. For example, given
this is a [[http://link][description]]
I would like to return
this is a description
I used re-builder to construct this regexp for a link:
\\[\\[[^\\[]+\\]\\[[^\\[]+\\]\\]
This is my function:
(defun flatten-string-with-links (string)
(replace-regexp-in-string "\\[\\[[^\\[]+\\]\\[[^\\[]+\\]\\]"
(lambda(s) (nth 2 (split-string s "[\]\[]+"))) string))
Instead of replacing the entire regexp sequence, it only replaces the trailing "]]". This is what it produces:
this is a [[http://link][descriptiondescription
I don't understand what's going wrong. Any help would be much appreciated.
UPDATE: I've improved the regex for the link. It's irrelevant to the question but if someone's gonna copy it they may as well get the better version.
Your problem is that split-string is clobbering the match data, which
replace-regexp-in-string is relying on being unchanged, since it is going to
go use that match data to decide which sections of the string to cut out. This
is arguably a doc bug in that replace-regexp-in-string does not mention that
your replacement function must preserve the match data.
You can work around by using save-match-data, which is a macro provided for
exactly this purpose:
(defun flatten-string-with-links (string)
(replace-regexp-in-string "\\[\\[[a-zA-Z:%#/\.]+\\]\\[[a-zA-Z:%#/\.]+\\]\\]"
(lambda (s) (save-match-data
(nth 2 (split-string s "[\]\[]+")))) string))

What is the Clojure equivalent of __FILE__ (found in Ruby & Perl)

In ruby I frequently use File.expand_path(File.dirname(__FILE__)) for loading config files or files with test data. Right now I'm trying to load some html files for a test in my clojure app and I can't figure out how to do it without hard coding the full path to the file.
edit:
I'm using leinigen if that helps in any way
ref: __FILE__ is a special literal which returns the filename (including any path) given to the program when executed. see (rubydoc & perldata)
*file*
API Reference (add *file* to the url)
Here is one way to replicate that in Clojure:
(defn dirname [path]
(.getParent (java.io.File. path)))
(defn expand-path [path]
(.getCanonicalPath (java.io.File. path)))
Then your Ruby line File.expand_path(File.dirname(__FILE__)) in Clojure would be this:
(expand-path (dirname *file*))
See Java interop docs for .getParent & .getCanonicalPath.
NB. I think *file* always returns the absolute (though not canonical) pathname/filename in Clojure. Whereas __FILE__ returns the the pathname/filename provided at execution. However I don't think these difference should effect what your trying to do?
/I3az/
Neither of the 9 point solutions is correct. *file* gives you a file relative to the classpath. Using .getCanonicalPath or .getAbsolutePath on *file* will give you a nonexistant file. As pointed out in this old thread, you need to use ClassLoader to resolve *file* correctly. Here's what I use to get the parent directory of the current file:
(-> (ClassLoader/getSystemResource *file*) clojure.java.io/file .getParent)
Based on user83510's answer above, the full answer is:
(def path-to-this-file
(clojure.string/join "/" [(-> (ClassLoader/getSystemResource *file*) clojure.java.io/file .getParent) (last (clojure.string/split *file* #"/"))]))
It ain't pretty but it works :P