I am making a macro which uses single quotes. However, whenever I parse the macro the single quote text like:
'java'
:is expanded to:
(quote java')
Does anyone know a way around this so that it doesn't expand to the quoted form?
Update
I have a kind of working workaround for this. I use:
(map (fn[x]
(if (.startsWith (str x) "(quote ")
(apply str "'" (rest x))
x)
: and this at least converts the 'text' to the string "'text'" which works for me
Clojure macros apply to the result of the clojure reader's parsing of the source text. Has two effects:
You will only get valid clojure datastructures as arguments to a macro.
You can only output one valid clojure datastructure from a macro.
One of the consequences of this is that certain syntactical constructs can not made to work using macros (since they cannot be read) and require a different reader (meaning you cannot mix them into normal clojure source files).
As an example:
(`foo`)
is invalid syntax.
It looks like you're trying to make a string with single quotes wrapping java. To do this you need to use a backslash to escape the single quotes.
"\'java\'"
You were quoting the symbol java' which wasn't going to give you what you wanted.
Related
I am trying to write a macro that generates patterns for the core.match macro.
(defmacro match2
[state i predecessor]
`(match ~[state]
[(~(vec (concat (repeat i '_)
predecessor
'(& r)))
:seq)] ~i
:else false))
And this works fine if I use it directly with hardcoded predecessor:
(match2 ["B"] 0 ["B"]) ; 0
So far everything is fine, but if I try to pass the predecessor using function call:
(match2 ["B"] 0 ((fn [] ["B"]))) ; AssertionError Invalid list syntax [] in (fn [] ["B"])
The problem is that because match2 is a macro clojure won't evaluate the function call, and will just pass the form as it is. The unevaluated form then goes to core.match (again unevaluated, because core.match is itself a macro) and core.match throws exception because the form is not correct pattern.
How can I force evaluation on macro argument? Or any other workaround?
I was hinted that this is usually done with a second macro, but my attempts yielded no good results.
I see two options. Use eval in your macro.
Or, you could have your macro not call the match macro. Have it call another function which calls the match macro. That will force evaluation en route to match.
Here is a good article to read about this type of problem:
http://amalloy.hubpages.com/hub/Clojure-macro-writing-macros
core.match is a compiler. It turns some forms into executable expressions. The forms it can process must respect a syntax, hence the assert throw. As a macro, it compiles at... compile time. However hard you try, you cannot have it compile the result of runtime expressions.
Even if you manage to get (fn [] ["B"]) evaluated at compile time so to feed the value to match, this is not your goal I presume. What you're trying to do is to feed match with expressions evaluated by your program's logic. Been there, sorry to say it is not possible with core.match, which D. Nolen confirmed.
Nevertheless, matchure can do just that: create match functions / expressions at runtime, see fn-match. It is unmaintained AFAIK but just works. I've patched it some time ago to use clj 1.6, here.
I read that data > functions > macros
Say you want to evaluate code in a postfix fashion.
Which approach would be better?
;; Macro
(defmacro reverse-fn [expression]
(conj (butlast expression) (last expression)))
(reverse-fn ("hello world" println))
; => "hello world"
;; Function and data
(def data ["hello world" println])
(defn reverse-fn [data]
(apply (eval (last data)) (butlast data)))
(reverse-fn ["hello world" println])
; => "hello world"
Thanks!
If you require different evaluation behavior for any kind of data in your code macros are your best choice because they can transform unevaluated data at compile time to the code you'd like to be evaluated instead.
Clojure has a programmatic macro system which allows the compiler to be extended by user code. Macros can be used to define syntactic constructs which would require primitives or built-in support in other languages. (http://clojure.org/macros)
The example you provide has specifically that requirement ("evaluate code in a postfix fashion") which is why a macro is the correct choice.
Your macro is better than your function: a macro is better than a function employing eval.
However, the function need not employ eval. You could write it
(defn reverse-fn [data]
(apply (last data) (butlast data)))
Then, for example, as before,
(reverse-fn [3 inc])
=> 4
On a related topic, you might find this explanation of transducers interesting.
Edit:
Notice that functions are literals, in the sense that a function evaluates to itself:
((eval +) 1 1)
=> 2
In general:
Macros have their use however; macros expand at the point they are encountered so you will have one or more code blocks being inlined in the resulting byte code. They are ideal for encapsulating High Order DSL terminologies.
Functions, on the other hand, are wonderful for reuse where you localize the purity of the function and it can be called from multiple other functions without increasing the code footprint. They are ideal for localized or global usage.
REPL behavior consideration: A single function is easier to rework without worrying about fully evaluating the entire source file(s) to ensure all macro reference expansions get updated.
Hope this helps
Simple rules are the best: Use a function if you can, a macro if you must.
I have a large lazy seq of lines that I want to write to a file. In C#, I would use System.IO.File/WriteAllLines which has an overload where the lines are either string[] or IEnumerable<string>.
I want to do this without using reflection at runtime.
(set! *warn-on-reflection* true)
(defn spit-lines [^String filename seq]
(System.IO.File/WriteAllLines filename seq))
But, I get this reflection warning.
Reflection warning, ... - call to WriteAllLines can't be resolved.
In general I need to know when reflection is necessary for performance reasons, but I don't care about this particular method call. I'm willing to write a bit more code to make the warning go away, but not willing to force all the data into memory as an array. Any suggestions?
Here are two options to consider, depending on whether you are using Clojure's core data structures.
Convert from a seq to an IEnumerable<string> with Enumerable.Cast from LINQ
This option will work for any IEnumerable that contains only strings.
(defn spit-lines [^String filename a-seq]
(->> a-seq
(System.Linq.Enumerable/Cast (type-args System.String))
(System.IO.File/WriteAllLines filename)))
Type Hint to force the caller to supply IEnumerable<string>
If you want to use a type hint, do this. But watch out, the clojure data structures do not implement IEnumerable<String>, so this could lead to a runtime exception.
^|System.Collections.Generic.IEnumerable`1[System.String]|
Wrapping the full CLR name of the type in vertical pipes (|) lets you specify characters that are otherwise illegal in Clojure syntax.
(defn spit-lines [^String filename ^|System.Collections.Generic.IEnumerable`1[System.String]| enumerable-of-string]
(System.IO.File/WriteAllLines filename enumerable-of-string))
Here's the exception from (spit-lines "filename.txt" #{}) when passing a set to the type-hinted version:
System.InvalidCastException: Unable to cast object of type 'clojure.lang.PersistentTreeSet' to type 'System.Collections.Generic.IEnumerable`1[System.String]'.
More information about specifying types.
I have written several functions that input strings and use varying regular expressions to search for patterns within the strings. All of the functions work on the same input [string]. What is the optimal way to combine all such functions into a single function?
I had tried combining the all of the regular expressions into a single regex, but ran into issues of degeneracy. Whereby the pattern fit multiple regular expressions and was outputting incorrect results. Next, I tried using the threading arrows -> and ->> but was unable to get those to work. I believe this might be the right option to use, but could not get the functions to run properly. So I am unable to test my hypothesis.
As an example of two functions to combine consider the following:
(defn fooip [string]
(re-seq #"\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b" string))
and
(defn foophone [string]
(re-seq #"[0-9]{3}-?[0-9]{3}-?[0-9]{4}" s))
If you have multiple functions that you want to combine into a function that will return the result of applying each function to the same input, that is exactly the purpose of juxt.
(def foo (juxt foophone fooip))
(foo "555-555-5555 222.222.222.222 888-888-8888")
;=> [("555-555-5555" "888-888-8888") ("222.222.222.222")]
Your question is a little vague, but the threading arrows' purpose is to apply multiple functions sequentially to the output of each other: (-> 1 inc inc inc), for example, is equivalent to (inc (inc (inc 1))).
From your code samples, it looks like you have multiple regexes you want to match against a single input string. The simple way to do that is to use for:
(for [r [#"foo" #"bar" #"baz"]] (re-seq r s))
To check for both patterns you can use or:
(defn phone-or-ip [s]
(or (matchphone s) (matchip s)))
There isn't one proper way to combine functions. It depends what you want to do.
P.S. There are ways to combine the regexps themselves. The naïve way is to just use | and parentheses to combine the two. I think there are optimizers, which can improve such patterns.
I'm learning Clojure and trying to understand reader, quoting, eval and homoiconicity by drawing parallels to Python's similar features.
In Python, one way to avoid (or postpone) evaluation is to wrap the expression between quotes, eg. '3 + 4'. You can evaluate this later using eval, eg. eval('3 + 4') yielding 7. (If you need to quote only Python values, you can use repr function instead of adding quotes manually.)
In Lisp you use quote or ' for quoting and eval for evaluating, eg. (eval '(+ 3 4)) yielding 7.
So in Python the "quoted" stuff is represented by a string, whereas in Lisp it's represented by a list which has quoteas first item.
My question, finally: why does Clojure allow (eval 3) although 3 is not quoted? Is it just the matter of Lisp style (trying to give an answer instead of error wherever possible) or are there some other reasons behind it? Is this behavior essential to Lisp or not?
The short answer would be that numbers (and symbols, and strings, for example) evaluate to themselves. Quoting instruct lisp (the reader) to pass unevaluated whatever follows the quote. eval then gets that list as you wrote it, but without the quote, and then evaluates it (in the case of (eval '(+ 3 4)), eval will evaluate a function call (+) over two arguments).
What happens with that last expression is the following:
When you hit enter, the expression is evaluated. It contain a normal function call (eval) and some arguments.
The arguments are evaluated. The first argument contains a quote, which tells the reader to produce what is after the quote (the actual (+ 3 4) list).
There are no more arguments, and the actual function call is evaluated. This means calling the eval function with the list (+ 3 4) as argument.
The eval function does the same steps again, finding the normal function + and the arguments, and applies it, obtaining the result.
Other answers have explained the mechanics, but I think the philosophical point is in the different ways lisp and python look at "code". In python, the only way to represent code is as a string, so of course attempting to evaluate a non-string will fail. Lisp has richer data structures for code: lists, numbers, symbols, and so forth. So the expression (+ 1 2) is a list, containing a symbol and two numbers. When evaluating a list, you must first evaluate each of its elements.
So, it's perfectly natural to need to evaluate a number in the ordinary course of running lisp code. To that end, numbers are defined to "evaluate to themselves", meaning they are the same after evaluation as they were before: just a number. The eval function applies the same rules to the bare "code snippet" 3 that the compiler would apply when compiling, say, the third element of a larger expression like (+ 5 3). For numbers, that means leaving it alone.
What should 3 evaluate to? It makes the most sense that Lisp evaluates a number to itself. Would we want to require numbers to be quoted in code? That would not be very convenient and extremely problematic:
Instead of
(defun add-fourtytwo (n)
(+ n 42))
we would have to write
(defun add-fourtytwo (n)
(+ n '42))
Every number in code would need to be quoted. A missing quote would trigger an error. That's not something one would want to use.
As a side note, imagine what happens when you want to use eval in your code.
(defun example ()
(eval 3))
Above would be wrong. Numbers would need to be quoted.
(defun example ()
(eval '3))
Above would be okay, but generating an error at runtime. Lisp evaluates '3 to the number 3. But then calling eval on the number would be an error, since they need to be quoted.
So we would need to write:
(defun example ()
(eval ''3))
That's not very useful...
Numbers have be always self-evaluating in Lisp history. But in earlier Lisp implementations some other data objects, like arrays, were not self-evaluating. Again, since this is a huge source of errors, Lisp dialects like Common Lisp have defined that all data types (other than lists and symbols) are self-evaluating.
To answer this question we need to look at eval definition in lisp. E.g. in CLHS there is definition:
Syntax: eval form => result*
Arguments and Values:
form - a form.
results - the values yielded by the evaluation of form.
Where form is
any object meant to be evaluated.
a symbol, a compound form, or a self-evaluating object.
(for an operator, as in <<operator>> form'') a compound form having that operator as its first element.A quote form is a
constant form.''
In your case number "3" is self-evaluating object. Self-evaluating object is a form that is neither a symbol nor a cons is defined to be a self-evaluating object. I believe that for clojure we can just replace cons by list in this definition.
In clojure only lists are interpreted by eval as function calls. Other data structures and objects are evaluated as self-evaluating objects.
'(+ 3 4) is equal to (list '+ 3 4). ' (transformed by reader to quote function) just avoid evaluation of given form. So in expression (eval '(+ 3 4)) eval takes list data structure ('+ 3 4) as argument.