There are a large number of web site which praise Lisp but I came across this page https://matthias.benkard.de/journal/110 which has this code:
((lambda([])((lambda(|| |()| |(| |)|)(+ || |(| 1 |)| |()| |(| |(| |(|)) [] [] [] [])) 0)
What does this code do? I am reluctant to try this code myself without knowing what it actually does.
In the conclusion part, it is pointed out that the page was written on 1st of April, but does the above code do anything at all?
Well this is a post joking about java and lisp, it has no sense and I think that with every language you can write weird code like this:
I personally like this with javascript:
2016-07-11 15:08:33 ☆ |ruby-2.2.3#laguna| Antonios-MBP in ~
○ → node
> Array(16).join("lol" - 2) + " Batman!";
'NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN Batman!'
>
Going into the code but a little bit formatted:
((lambda ([])
((lambda (|| |()| |(| |)|)
(+ || |(| 1 |)| |()| |(| |(| |(|))
[] [] [] []))
0)
for this we need to know two things about common lisp the sintaxis of the lambda function and a little bit about symbols sintaxis and variables:
first trick: [] is a variable name
CL-USER> (defparameter [] 2)
[]
CL-USER> (+ [] [])
4
second trick: you can put any name to a symbol within |symbol-name| so
(|| |()| |(| |)|) so this are only the entry variables for the second lambda, finally, this lambdas have the body and the excution parameter for the first lambda is 0 and for the intern lambda four []
So this can be rewriten as:
((lambda (a)
((lambda (x y z k)
(+ x z 1 k y z z z))
a a a a))
0)
and finally is easy to guess that this will be one
Related
I'm new to Racket and I was hoping to get more insights in the these two operators: , & ,#.
There's very little documentation of these new operators, however, to my understanding the former (,) unquotes everything if its is followed by a list. And the latter (,#) splices the values.
For example if the following is typed in the Dr. Racket interpreter:
(define scores '(1 3 2))
(define pets '(dog cat))
and then the following query is made:
`(,scores ,#pets)
this would yield : '((1 3 2) dog cat)
It would be appreciated if I could get more details, definitions and more examples about these operators.
Thanks in advance.
A single quote followed by the written representation of a value
will produce that value:
Example:
'(1 x "foo")
will produce a value that prints as (1 x "foo").
Suppose now that I don't want a literal symbol x in the list.
I have a variable x in my program, and I want to insert
the value to which x is bound.
To mark that I want the value of x rather than the symbol x,
I insert a comma before x:
'(1 ,x "foo")
It won't work as-is though - I now get a value that has a literal comma as well as a symbol x. The problem is that quote does not know about the comma convention.
Backtick or backquote knows about the comma-convention, so that will give the correct result:
> `(1 ,x "foo")
(1 3 "foo") ; if the value of x is 3
Now let's say x is the list (a b).
> `(1 ,x "foo")
(1 (a b) "foo") ; if the value of x is (a b)
This looks as expected. But what if I wanted (1 a b "foo")
as the result? We need a way so show "insert the elements of a list".
That's where ,# comes into the picture.
> `(1 ,#x "foo")
(1 a b "foo") ; if the value of x is (a b)
They are "reader abbreviations" or "reader macros". They are introduced in the section of the Racket guide on quasiquotation. To summarize:
`e reads as (quasiquote e)
,e reads as (unquote e)
,#e reads as (unquote-splicing e)
Because Racket's printer uses the same abbreviations by default, it can be confusing to test this yourself. Here are a few examples that should help:
> (equal? (list 'unquote 'abc) (read (open-input-string ",abc")))
#t
> (writeln (read (open-input-string ",abc")))
(unquote abc)
A more exhaustive description of the Racket reader is in the section on The Reader in the Racket Reference. A list of reader abbreviations is in the Reading Quotes subsection.
Problem: How to handle a catch-all parameter after & in a macro, when the arguments to be passed are sequences, and the catch-all variable needs to be dealt with as a sequence of sequences? What gets listed in the catch-all variable are literal expressions.
This is a macro that's intended to behave roughly Common Lisp's mapc, i.e. to do what Clojure's map does, but only for side-effects, and without laziness:
(defmacro domap [f & colls]
`(dotimes [i# (apply min (map count '(~#colls)))]
(apply ~f (map #(nth % i#) '(~#colls)))))
I've come to realize that this is not a good way to write domap--I got good advice about that in this question. However, I'm still wondering about the tricky macro problem that I encountered along the way.
This works if the collection is passed as a literal:
user=> (domap println [0 1 2])
0
1
2
nil
But doesn't work in other situations like this one:
user=> (domap println (range 3))
range
3
nil
Or this one:
user=> (def nums [0 1 2])
#'user/nums
user=> (domap println nums)
UnsupportedOperationException count not supported on this type: Symbol clojure.lang.RT.countFro (RT.java:556)
The problem is that it's literal expressions that are inside colls. This is why the macro domap works when passed a sequence of integers, but not in other situations. Notice the instances of '(nums):
user=> (pprint (macroexpand-1 '(domap println nums)))
(clojure.core/dotimes
[i__199__auto__
(clojure.core/apply
clojure.core/min
(clojure.core/map clojure.core/count '(nums)))]
(clojure.core/apply
println
(clojure.core/map
(fn*
[p1__198__200__auto__]
(clojure.core/nth p1__198__200__auto__ i__199__auto__))
'(nums))))
I've tried various combinations of ~, ~#, ', let with var#, etc. Nothing's worked. Maybe it's a mistake to try to write this as a macro, but I'd still be curious how to write a variadic macro that takes complex arguments like these.
Here is why your macro does not work:
'(~#colls) This expression creates a quoted list of all colls. E. g. if you pass it (range 3), this expression becomes '((range 3)), so the literal argument will be one of your colls, preventing evaluation of (range 3) certainly not what you want here.
Now if you would not quote (~#colls) inside the macro, of course they would become a literal function invocation like ((range 3)), which makes the compiler throw after macroexpansion time (it will try to eval ((0 1 2))).
You can use list to avoid this problem:
(defmacro domap [f & colls]
`(dotimes [i# (apply min (map count (list ~#colls)))]
(apply ~f (map #(nth % i#) (list ~#colls)))))
=> (domap println (range 3))
0
1
2
However one thing here is terrible: Inside the macro, the entire list is created twice. Here is how we could avoid that:
(defmacro domap [f & colls]
`(let [colls# (list ~#colls)]
(dotimes [i# (apply min (map count colls#))]
(apply ~f (map #(nth % i#) colls#)))))
The colls are not the only thing that we need to prevent from being evaluated multiple times. If the user passes something like (fn [& args] ...) as f, that lambda would also be compiled in every step.
Now this is the exactly the scenario where you should ask yourself why you are writing a macro. Essentially, your macro has to make sure all arguments are eval'd without transforming them in any way before. Evaluation comes gratis with functions, so let's write it as a function instead:
(defn domap [f & colls]
(dotimes [i (apply min (map count colls))]
(apply f (map #(nth % i) colls))))
Given what you want to achieve, notice there is a function to solve that already, dorun which simply realizes a seq but does not retain the head. E. g.:
`(dorun (map println (range 3)))
would do the trick as well.
Now that you have dorun and map, you can simply compose them using comp to achieve your goal:
(def domap (comp dorun map))
=> (domap println (range 3) (range 10) (range 3))
0 0 0
1 1 1
2 2 2
I am trying define symbols a and b in following way
a + 1 1 b
2
I am trying to do this by using define-symbol-macro
(define-symbol-macro a '( )
(define-symbol-macro b ') )
but this way is not working.
What Lisp does with source code
Common Lisp is an incredibly flexible language, in part because its source code can be easily represented using the same data structures that are used in the language. The most common form of macro expansion transforms the these structures into other structures. These are the kind of macros that you can define with define-symbol-macro, define-compiler-macro, defmacro, and macrolet. Before any of those kind of macroexpansions can be performed, however, the system first needs to read the source from an input stream (typically a file, or an interactive prompt). That's the reader's responsibility. The reader also is capable of executing some special actions when it encounters certain characters, such ( and '. What you're trying to do probably needs to be happening down at the reader level, if you want to have, e.g., (read-from-string "a + 1 1 b") return the list (+ 1 1), which is what you want if you want (eval (read-from-string "a + 1 1 b")) to return 2. That said, you could also define a special custom language (like loop does) where a and b are treated specially.
Use set-macro-character, not define-symbol-macro
This isn't something that you would do using symbol-macros, but rather with macro characters. You can set macro characters using the aptly named set-macro-character. For instance, in the following, I set the macro character for % to be a function that reads a list, using read-delimited-list that should be terminated by ^. (Using the characters a and b here will prove very difficult, because you won't be able to write things like (set-macro-character ...) afterwards; it would be like writing (set-m(cro-ch(r(cter ...), which is not good.)
CL-USER> (set-macro-character #\% (lambda (stream ignore)
(declare (ignore ignore))
(read-delimited-list #\^ stream)))
T
CL-USER> % + 1 1 ^
2
The related set-syntax-from-char
There's a related function that almost does what you want here, set-syntax-from-char. You can use it to make one character behave like another. For instance, you can make % behave like (
CL-USER> (set-syntax-from-char #\% #\()
T
CL-USER> % + 1 1 )
2
However, since the macro character associated with ( isn't looking for a character that has the same syntax as ), but an actual ) character, you can't simply replace ) with ^ in the same way:
CL-USER> (set-syntax-from-char #\^ #\))
T
CL-USER> % + 1 1 ^
; Evaluation aborted on #<SB-INT:SIMPLE-READER-ERROR "unmatched close parenthesis" {1002C66031}>.
set-syntax-from-char is more useful when there's an existing character that, by itself does something that you want to imitate. For instance, if you wanted to make ! an additional quotation character:
CL-USER> (set-syntax-from-char #\! #\')
T
CL-USER> (list !a !(1 2 3))
(A (1 2 3))
or make % be a comment character, like it is in LaTeX:
CL-USER> (set-syntax-from-char #\% #\;)
T
CL-USER> (list 1 2 % 3 4
5 6)
(1 2 5 6)
But consider why you're doing this at all…
Now, even though you can do all of this, it seems like something that would be utterly surprising to anyone who ran into it. (Perhaps you're entering an obfuscated coding competition? ;)) For the reasons shown above, doing this with commonly used characters such as a and b will also make it very difficult to write any more source code. It's probably a better bet to define an entirely new readtable that does what you want, or even write a new parser. even though (Common) Lisp lets you redefine the language, there are still things that it probably makes sense to leave alone.
A symbol-macro is a symbol that stands for another form. Seems like you want to look at reader macros.
http://clhs.lisp.se/Body/f_set__1.htm
http://dorophone.blogspot.no/2008/03/common-lisp-reader-macros-simple.html
I would second Rainer's comment though, what are you trying to make?
Ok so I love your comment on the reason for this and now I know this is for 'Just because it's lisp' then I am totally on board!
Ok so you are right about lisp being great to use to make new languages because we only have to 'compile' to valid lisp code and it will run. So while we cant use the normal compiler to do the transformation of the symbols 'a and 'b to brackets we can write this ourselves.
Ok so lets get started!
(defun symbol-name-equal (a b)
(and (symbolp a) (symbolp b) (equal (symbol-name a) (symbol-name b))))
(defun find-matching-weird (start-pos open-symbol close-symbol code)
(unless (symbol-name-equal open-symbol (nth start-pos code))
(error "start-pos does not point to a weird open-symbol"))
(let ((nest-index 0))
(loop :for item :in (nthcdr start-pos code)
:for i :from start-pos :do
(cond ((symbol-name-equal item open-symbol) (incf nest-index 1))
((symbol-name-equal item close-symbol) (incf nest-index -1)))
(when (eql nest-index 0)
(return i))
:finally (return nil))))
(defun weird-forms (open-symbol close-symbol body)
(cond ((null body) nil)
((listp body)
(let ((open-pos (position open-symbol body :test #'symbol-name-equal)))
(if open-pos
(let ((close-pos (find-matching-weird open-pos open-symbol close-symbol body)))
(if close-pos
(weird-forms open-symbol close-symbol
`(,#(subseq body 0 open-pos)
(,#(subseq body (1+ open-pos) close-pos))
,#(subseq body (1+ close-pos))))
(error "unmatched weird brackets")))
(if (find close-symbol body :test #'symbol-name-equal)
(error "unmatched weird brackets")
(loop for item in body collect
(weird-forms open-symbol close-symbol item))))))
(t body)))
(defmacro with-weird-forms ((open-symbol close-symbol) &body body)
`(progn
,#(weird-forms open-symbol close-symbol body)))
So there are a few parts to this.
First we have (symbol-name-equal), this is a helper function because we are now using symbols and symbols belong to packages. symbol-name-equal gives us a way of checking if the symbols have the same name ignoring what package they reside in.
Second we have (find-matching-weird). This is a function that takes a list and and index to an opening weird bracket and returns the index to the closing weird bracket. This makes sure we get the correct bracket even with nesting
Next we have (weird-forms). This is the juicy bit and what it does is to recursively walk through the list passed as the 'body' argument and do the following:
If body is an empty list just return it
if body is a list then
find the positions of our open and close symbols.
if only one of them is found then we have unmatched brackets.
if we find both symbols then make a new list with the bit between the start and end positions inside a nested list.
we then call weird forms on this result in case there are more weird-symbol-forms inside.
there are no weird symbols then just loop over the items in the list and call weird-form on them to keep the search going.
OK so that function transforms a list. For example try:
(weird-forms 'a 'b '(1 2 3 a 4 5 b 6 7))
But we want this to be proper lisp code that executes so we need to use a simple macro.
(with-weird-forms) is a macro that takes calls the weird-forms function and puts the result into our source code to be compiled by lisp. So if we have this:
(with-weird-forms (a b)
(+ 1 2 3 a - a + 1 2 3 b 10 5 b 11 23))
Then it macroexpands into:
(PROGN (+ 1 2 3 (- (+ 1 2 3) 10 5) 11 23))
Which is totally valid lisp code, so it will run!
CL-USER> (with-weird-forms (a b)
(+ 1 2 3 a - a + 1 2 3 b 10 5 b 11 23))
31
Finally if you have settled on the 'a' and 'b' brackets you could write another little macro:
(defmacro ab-lang (&rest code)
`(with-weird-forms (a b) ,#code))
Now try this:
(ab-lang a let* a a d 1 b a e a * d 5 b b b a format t "this stupid test gives: ~a" e b b)
Cheers mate, this was great fun to write. Sorry for dismissing the problem earlier on.
This kind of coding is very important as ultimately this is a tiny compiler for our weird language where symbols can be punctuation. Compilers are awesome and no language makes it as effortless to write them as lisp does.
Peace!
I'm trying (as a self-learning exercise) to create a Clojure macro that will generate code to apply a function to a sequence of integers and sum the result, e.g.
f(0) + f(1) + f(2) + f(3)
This is my attempt:
(defmacro testsum [func n]
`(fn [x#] (+ ~#( map (fn [i] `(~func x#)) (range n)))))
However something seems to go wrong with the x# gensym and I end up with two different versions of x and hence the function doesn't work:
(macroexpand '(testsum inc 3))
gives:
(fn* ([x__809__auto__]
(clojure.core/+
(inc x__808__auto__)
(inc x__808__auto__)
(inc x__808__auto__))))
This is pretty much exactly what I want apart from the different 809 and 808 versions of x.....
What am I doing wrong? I thought that the auto gensym was meant to create a single unique symbol for exactly this kind of purpose? Is there a better way of doing this?
foo#-style gensyms are valid only inside the syntax-quote where they were created. In your code, the two x#s are created in different syntax-quote blocks:
(defmacro testsum [func n]
`(fn [x#] (+ ~#( map (fn [i] `(~func x#)) (range n)))))
^- s-q1 ^-unquote ^- s-q2
To fix this, use an explicit (gensym) call:
(defmacro testsum [func n]
(let [x (gensym "x")]
`(fn [~x] (+ ~#(map (fn [i] `(~func ~x)) (range n))))))
And the macro expansion ((macroexpand '(testsum inc 3))):
(fn* ([x4966] (clojure.core/+ (inc x4966) (inc x4966) (inc x4966))))
I learned quite a bit of scheme from SICP but am more interested in common lisp now. I know common lisp's fold is reduce, with special arguments for left or right folding, but what is the equivalent of unfold? Googling has not helped much. In fact I get the impression there is no unfold???
Common Lisp has (loop ... collect ...). Compare
(loop for x from 1 to 10 collect (* x x))
with its equivalence using unfold:
(unfold (lambda (x) (> x 10))
(lambda (x) (* x x))
(lambda (x) (+ x 1))
1)
In general, (unfold p f g seed) is basically
(loop for x = seed then (g x) until (p x) collect (f x))
Edit: fix typo
The common lisp hyperspec doesn't define an unfold function, but you can certainly write your own. Its scheme definition translates almost symbol for symbol.