Clojure macro that doesn't need space next to it - macros

Trying to create a macro form of Haskell's lambda syntax, I'm pretty close except one last tweak, the / (which should be a \, but can't grumble..) needs a space next to it, is there any way to make it so my macro doesn't need space between it and it's first argument?
for instance:
(reduce (/x y -> x y) [1 2 3])
instead of:
(reduce (/ x y -> x y) [1 2 3])
I suspect this isn't possible, but only way to know for sure is to ask people who know, so what's the word?

No. Macros cannot change the lexical syntax of the language. That requires read-macros, which Clojure doesn't have.

No, but if you wanted to do something more ambitious, you could define another macro with-haskell-lambdas that you wrap your entire namespace in. That macro could look through all the forms under it, eg with tree-seq, find symbols of the form /x, and replace them with / x instead.

Related

How to define a function that returns half of input, in two different ways?

I am reading a Gentle Introduction to Symbolic Computation and it asks this question. Basically, the previous content deals with making up bigger functions with small ones. (Like 2- will be made of two 1- (decrement operators for lisp))
So one of the questions is what are the two different ways to define a function HALF which returns one half of its input. I have been able to come up with the obvious one (dividing number by 2) but then get stuck. I was thinking of subtracting HALF of the number from itself to get half but then the first half also has to be calculated...(I don't think the author intended to introduce recursion so soon in the book, so I am most probably wrong).
So my question is what is the other way? And are there only two ways?
EDIT : Example HALF(5) gives 2.5
P.S - the book deals with teaching LISP of which I know nothing about but apparently has a specific bent towards using smaller blocks to build bigger ones, so please try to answer using that approach.
P.P.S - I found this so far, but it is on a completely different topic - How to define that float is half of the number?
Pdf of book available here - http://www.cs.cmu.edu/~dst/LispBook/book.pdf (ctrl+f "two different ways")
It's seems to be you are describing peano arithmetic. In practice it works the same way as doing computation with fluids using cups and buckets.
You add by taking cups from the source(s) to a target bucket until the source(s) is empty. Multiplication and division is just advanced adding and substraction. To halve you take from source to two buckets in alterations until the source is empty. Of course this will either do ceil or floor depending on what bucket you choose to use as answer.
(defun halve (x)
;; make an auxillary procedure to do the job
(labels ((loop (x even acc)
(if (zerop x)
(if even (+ acc 0.5) acc)
(loop (- x 1) (not even) (if even (+ acc 1) acc)))))
;; use the auxillary procedure
(loop x nil 0)))
Originally i provided a Scheme version (since you just tagged lisp)
(define (halve x)
(let loop ((x x) (even #f) (acc 0))
(if (zero? x)
(if even (+ acc 0.5) acc)
(loop (- x 1) (not even) (if even (+ acc 1) acc)))))
Edit: Okay, lets see if I can describe this step by step. I'll break the function into multiple lines also.
(defun half (n)
;Takes integer n, returns half of n
(+
(ash n -1) ;Line A
(if (= (mod n 2) 1) .5 0))) ;Line B
So this whole function is an addition problem. It is simply adding two numbers, but to calculate the values of those two numbers requires additional function calls within the "+" function.
Line A: This performs a bit-shift on n. The -1 tells the function to shift n to the right one bit. To explain this we'll have to look at bit strings.
Suppose we have the number 8, represented in binary. Then we shift it one to the right.
1000| --> 100|0
The vertical bar is the end of the number. When we shift one to the right, the rightmost bit pops off and is not part of the number, leaving us with 100. This is the binary for 4.
We get the same value, however if we perform the shift on nine:
1001| --> 100|1
Once, again we get the value 4. We can see from this example that bit-shifting truncates the value and we need some way to account for the lost .5 on odd numbers, which is where Line B comes in.
Line B: First this line tests to see if n is even or odd. It does this by using the modulus operation, which returns the remainder of a division problem. In our case, the function call is (mod n 2), which returns the remainder of n divided by 2. If n is even, this will return 0, if it is odd, it will return 1.
Something that might be tripping you up is the lisp "=" function. It takes a conditional as its first parameter. The next parameter is the value the "=" function returns if the conditional is true, and the final parameter is what to return if the conditional is false.
So, in this case, we test to see if (mod n 2) is equal to one, which means we are testing to see if n is odd. If it is odd, we add .5 to our value from Line A, if it is not odd, we add nothing (0) to our value from Line A.

Compare two lists of numbers in elisp?

So, I can do this (using cl):
(loop for x in my-list
for y in my-other-list
if (> x y) return t
if (< x y) return nil)
But I really feel like this should be as easy as (list> my-list my-other-list) But I can find absolutely no evidence that this function exists by any name. In fact, I can't even find any general documentation for comparing lists at all. This makes me feel like I must be missing something.
Do I have do define (list>) myself, or have I missed great swaths of documentation in my haste and confusion?
And if I have to define it myself, can you do a better job? I'm not really an elisp hacker.
How about this:
(require 'cl)
(every '> my-list my-other-list)
The closest Elisp provides is probably version-list-<.

Why does let require a vector?

I never really thought about this until I was explaining some clojure code to a coworker who wasn't familiar with clojure. I was explaining let to him when he asked why you use a vector to declare the bindings rather than a list. I didn't really have an answer for him. But the language does restrict you from using lists:
=> (let (x 1) x)
java.lang.IllegalArgumentException: let requires a vector for its binding (NO_SOURCE_FILE:0)
Why exactly is this?
Mostly readability, I imagine. Whenever bindings are needed in Clojure, a vector is pretty consistently used. A lot of people agree that vectors for bindings make things flow better, and make it easier to discern what the bindings are and what the running code is.
Just for fun:
user=> (defmacro list-let [bindings & body] `(let ~(vec bindings) ~#body))
#'user/list-let
user=> (macroexpand-1 '(list-let (x 0) (println x)))
(clojure.core/let [x 0] (println x))
user=> (list-let (x 0 y 1) (println x y))
0 1
nil
This is an idiom from Scheme. In many Scheme implementations, square brackets can be used interchangeably with round parentheses in list literals. In those Scheme implementations, square brackets are often used to distinguish parameter lists, argument lists and bindings from S-expressions or data lists.
In Clojure, parentheses and brackets mean different things, but they are used the same way in binding declarations.
Clojure tries very hard to be consistent. There is no technical reason with a list form could not have been used in let, fn, with-open, etc... In fact, you can create your own my-let easily enough that uses one instead. However, aside from standing out visibly, the vector is used consistently across forms to mean "here are some bindings". You should strive to uphold that ideal in your own code.
my guess is that it's a convention
fn used it, defn used it, loop uses.
it seems that it's for everything that resembles a block of code that has some parameters; more specific, the square brackets are for marking those parameters
other forms for blocks of code don't use it, like if or do. they don't have any parameters
Another way to think about this is that let is simply derived from lambda. These two expressions are equivalent:
((fn [y] (+ y 42)) 10)
(let [y 10] (+ 42 y))
So as an academic or instructional point, you could even write your own very rudimentary version of let that took a list as well as a vector:
(defmacro my-let [x body]
(list (list `fn[(first x)]
`~body)
(last x)))
(my-let (z 42) (* z z))
although there would be no practical reason to do this.

Trouble with this macro

Embarrassingly enough, I'm having some trouble designing this macro correctly.
This is the macro as I have it written:
(defmacro construct-vertices
[xs ys]
(cons 'draw-line-strip
(map #(list vertex %1 %2) xs ys)))
It needs to take in two collections or seqs, xs and ys, and I need it to give me…
(draw-line-strip (vertex 0 1) (vertex 1 1)
(vertex 3 3) (vertex 5 6)
(vertex 7 8))
…for xs = [0 1 3 5 7] and ys = [1 1 3 6 8].
This works just fine if I give my macro plain 'n' simple vectors (e.g. [1 2 3 4] and [2 3 4 5]) but doesn't work if I give it a lazy-seq/anything that needs to be evaluated like (take 16 (iterate #(+ 0.1 %1) 0)) and (take 16 (cycle [0 -0.1 0 0.1])))).
I realize that this is because these are passed to the macro unevaluated, and so I get, for example, (vertex take take) as my first result (I do believe). Unfortunately, everything I've tried to first evaluate these and then carry out my macro-rewriting has failed/looked terribly hacky.
I'm sure I'm missing some sort of basic syntax-quote/unquote pattern here–I'd love some help/pointers!
Thanks so much.
EDIT I should mention, draw-line-strip is a macro, and vertex creates an OpenGL vertex; they are both part of the Penumbra Clojure+OpenGL library.
EDIT 2 This is for a custom graphing tool I need, and the primary motivation for creating it was to be faster than JFreeCharts and company.
EDIT 3 I suppose I should note that I do have a macro version working, it's just horrid and hacky as I mentioned above. It uses eval, as demonstrated below, but like this:
(defmacro construct-vertices
[xs ys]
(cons 'draw-line-strip
(map #(list vertex %1 %2) (eval xs) (eval ys))))
Unfortunately, I get…
error: java.lang.ClassFormatError: Invalid this class index 3171 in constant pool in class file tl/core$draw_l$fn__9357 (core.clj:14)
…when using this with a few thousand-item long list(s). This is because I'm writing far too much into the pre-compiled code, and the classfile can't handle (I suppose) that much data/code. It looks like I need to, somehow, obtain a function version of draw-line-strip, as has been suggested.
I'm still open, however, to a more elegant, less hackish, macro solution to this problem. If one exists!
I looked at the macro expansion for draw-line-strip and noticed that it just wraps the body in a binding, gl-begin, and gl-end. So you can put whatever code inside it you want.
So
(defn construct-vertices [xs ys]
(draw-line-strip
(dorun (map #(vertex %1 %2) xs ys))))
should work.
Why not something like this, using function instead of macro:
(defn construct-vertices [xs ys]
(apply draw-line-strip (map #(list vertex %1 %2) xs ys)))
That should call draw-line-strip with required args. This example is not the best fit for macros, which shouldn't be used where functions can do.
Note: I didn't try it since I don't have slime set up on this box.
EDIT: Looking again, I don't know if you want to evaluate vertex before calling draw-line-strip. In that case function will look like:
(defn construct-vertices [xs ys]
(apply draw-line-strip (map #(vertex %1 %2) xs ys)))
If you really need draw-line-strip to be a macro and you want a fully general method of doing what the question text describes and you don't care too much about a bit of a performance hit, you could use eval:
(defn construct-vertices [xs ys]
(eval `(draw-line-strip ~#(map #(list 'vertex %1 %2) xs ys))))
; ^- not sure what vertex is
; and thus whether you need this quote
Note that this is terrible style unless it is really necessary.
This looks like a typical problem with some of the macro systems in Lisp. The usual Lisp literature applies. For example On Lisp by Paul Graham (uses Common Lisp).
Usually a macro uses the source it encloses and generates new source. If a macro call is (foo bar), and the macro should generate something different based on the value of bar, then this is generally not possible, since the value of bar is generally not available for the compiler. BAR really has only a value at runtime, not when the compiler expands the macros. So one would need to generate the right code at runtime - which might be possible, but which is usually seen as bad style.
In these macro systems macros can't be applied. A typical solution looks like this (Common Lisp):
(apply (lambda (a b c)
(a-macro-with-three-args a b c))
list-of-three-elements)
It is not always possible to use above solution, though. For example when the number of arguments varies.
It's also not a good idea that DRAW-LINE-STRIP is a macro. It should better be written as a function.

extract/slice/reorder lists in (emacs) lisp?

In python, you might do something like
i = (0, 3, 2)
x = [x+1 for x in range(0,5)]
operator.itemgetter(*i)(x)
to get (1, 4, 3).
In (emacs) lisp, I wrote this function called extract which does something similar,
(defun extract (elems seq)
(mapcar (lambda (x) (nth x seq)) elems))
(extract '(0 3 2) (number-sequence 1 5))
but I feel like there should be something built in? All I know is first, last, rest, nth, car, cdr... What's the way to go? ~ Thanks in advance ~
If your problem is the speed then use (vector 1 2 3 4 5) instead of a list, and (aref vec index) to get the element.
(defun extract (elems seq)
(let ((av (vconcat seq)))
(mapcar (lambda (x) (aref av x)) elems)))
If you're going to extract from the same sequence many times of course it make sense to store the sequence in a vector just once.
Python lists are indeed one-dimensional arrays, the equivalent in LISP are vectors.
I've only done simple scripting in elisp, but it's a relatively small language. And extract is a very inefficient function on linked lists, which is the default data structure in emacs lisp. So it's unlikely to be built-in.
Your solution is the best straightforward one. It's n^2, but to make it faster requires a lot more code.
Below is a guess at how it might work, but it might also be totally off base:
sort elems (n log n)
create a map that maps elements in sorted elem to their indices in original elem (probably n log n, maybe n)
iterate through seq and sorted elem. Keep only the indices in sorted elem (probably n, maybe n log n, depending on whether it's a hash map or a tree map)
sort the result by the values of the elem mapping (n log n)
From My Lisp Experiences and the Development of GNU Emacs:
There were people in those days, in 1985, who had one-megabyte machines without virtual memory. They wanted to be able to use GNU Emacs. This meant I had to keep the program as small as possible.
For instance, at the time the only looping construct was ‘while’, which was extremely simple. There was no way to break out of the ‘while’ statement, you just had to do a catch and a throw, or test a variable that ran the loop. That shows how far I was pushing to keep things small. We didn't have ‘caar’ and ‘cadr’ and so on; “squeeze out everything possible” was the spirit of GNU Emacs, the spirit of Emacs Lisp, from the beginning.
Obviously, machines are bigger now, and we don't do it that way anymore. We put in ‘caar’ and ‘cadr’ and so on, and we might put in another looping construct one of these days.
So my guess is, if you don't see it, it's not there.