I know that we use ; for commenting in Clojure, which is equivalent of // in Java. But I cannot understand why we need #_
Can someone please explain this? Is it used to ignore text? How is it different from ; if that is the case?
; is a line comment; it ignores the text from ; to the end of the line in your source. This also means, that sometimes a comment on the last line leads to lines with just closing parens, which usually is avoided. The main usecase for ; is to write comments for humans to read.
#_ is called
discard; it
ignores the next form, which means it is agnostic of line breaks in your
source file. This is primarily used to quickly "toggle" code. You can also stack #_. E.g. {#_#_ :a 42}.
Note, that there is also the (comment ...) macro, which throws away the body and returns nil; so the body must be "valid" and you are well advised not use it, where the result could cause havoc. This is primarily used to provide some "prove of concept" inside the source or code you can quickly run in the REPL, but should not run as part of the ns, or when you are to lazy to write a proper test.
Related
I was going through a library code in which they used #_. As gone through multiple references, I understand #_ is discard symbol, which tell the reader to ignore whatever comes next.
Why it is even needed in the first place? If we have something to be ignored, why can't we remove it or just comment it? What's the significance of #_ over commenting?
It's super handy when debugging or writing some altered code.
Say you have some massive function, and you want to comment it out for a bit. You have a few options:
You can use line comments:
; (defn some-huge-thing []
; ... Many lines)
But that's painful unless your IDE has an commenting shortcut, and even then it takes some work. Plus, I've found most IDE's handling of comment-shortcuts to work less than ideally. Sometimes they just add another "layer" of comments instead of removing the existing ones. Line comments also don't help if you only want to comment out a small piece of a function since they aren't context sensitive.
You could use comment:
(comment
(defn some-huge-thing []
... Many lines))
But I personally don't like comment because here, it requires either nesting the entire thing, or violating Parinfer just to add the comment. Also as #amalloy points out, it ends up expanding to nil, so it can only be used in a context where a stray nil won't effect anything.
... Or, you can use #_:
#_
(defn some-huge-thing []
... Many lines)
It doesn't require altering the function at all. It's just two keystrokes to put in, and two to remove. It also doesn't evaluate to nil; it's simply ignored. That means you can use it, for example, to comment out arguments inside of a function call.
I personally use #_ quite often when playing around with different implementations and when I'm trying to isolate a bug. It causes anything comming immediately after it to be ignored, so it's very easy to control what is and isn't executing.
In clojure, read-string followed by str will not return the original string, but the string for which the reader macros have been expanded:
(str (read-string "(def foo [] #(bar))"))
;"(def foo [] (fn* [] (bar)))"
This is problematic if we want to manipulate a small part of the code, far away from any reader macros, and get back a string representation that preserves the reader macros. Is there a work around?
The purpose of read is to build an AST of the code and as such the function does not preserve all the properties of the original text. Otherwise, it should keep track of the original code-layout (e.g. location of parenthesis, newlines, indentation (tabs/spaces), comments, and so on). If you have a look at LispReader.java, you can see that the reader macros are unconditionally applied (*read-eval* does not influence all reader macros).
Here is what I would recommend:
You can take inspiration of the existing LispReader and implement your own reader. Maybe it is sufficient to change the dispatch-table so that macro characters are directed to you own reader. You would also need to build runtime representations of the quoted forms and provide adequate printer functions for those objects.
You can process your original file with Emacs lisp, which can easily navigate the structure of your code and edit it as you wish.
Remark: you must know that what you are trying to achieve smells fishy. You might have a good reason to want to do this, but this looks needlessly complex without knowing why you want to work at the syntax level. It would help if you could provide more details.
I have a string which will evaluate to true or false, can I use macro and pass the string as parameter? I write the following, but the result is string of (= 0 0) instead of true. How to get true result?
(def a "(= 0 0)")
(defmacro test [code-string] code-string)
(test a)
update:
The purpose is replace dynamic SQL. Currently we store code like 'column_a > 1' in database, and then we will get the code, and assemble a sql like
select case when column_a>1 then 0 else 1 end as result from table
There are many such code, and I hope to use clojure run in parallel to speed it up. To use clojure I could store '(> row["column_a"] 1)' in database, and then in jdbc looping, call (> row["column_a"] 1) to do my logic, like storing some code section in database and need to run it.
As TaylanUB already said, Clojure provides eval to evaluate some expression at run-time. However, using eval is frowned upon unless you have very good reasons to use it. It's not clear what you're really intending to do, so it would be helpful to provide a more real world example. If you don't have one, you don't need eval.
Similarly, macros are used to transform code and are not run at run-time, instead the code to which the macro evaluates gets run. The typical approach would be to try to solve a problem with a mere function, only if a macro would buy you something in terms of applicability to a wider range of code, consider turning the code into a macro. Edit: take a look at some introduction to macros in Clojure, e.g. this part from Clojure from the ground up
No, you cannot directly use a string as code. Defmacro takes s-expressions not strings. Clojure might have something like read which can parse a string and make an s-expression out of it which you might then be able to execute as code via something like eval.
There is usually no good reason to put code in strings or other data structures which will exist during program execution anyway, try to just work with first-class functions instead. Or mention the precise problem you're trying to solve and people might be able to give better answers. This might be an instance of the XY problem.
Note: I don't know Clojure, but all of this is pretty Lisp-generic.
(defn eval-code [code-string]
(eval (read-string code-string)))
(eval-code "(= 0 0)")
;; you don't need macro here.
OK, so I've set up a complete Bison grammar (+ its Lex counterpart) and this is what I need :
Is there any way I can set up a grammar rule so that a specific portion of input is excluded from being parsed, but instead retrieved as-is?
E.g.
external_code : EXT_CODE_START '{' '}';
For instance, how could I get the part between the curly brackets as a string, without allowing the parser to consume it (since it'll be "external" code, it won't abide by my current language rules... so, it's ok - text is fine).
How would you go about that?
Should I tackle the issue by adding a token to the Lexer? (same as I do with string literals, for example?)
Any ideas are welcome! (I hope you've understood what I need...)
P.S. Well, I also thought of treating the whole situation pretty much as I do with C-style multiline comments (= capture when the comment begins, in the Lexer, and then - from within a custom function, keep going until the end-of-comment is found). That'd definitely be some sort of solution. But isn't there anything... easier?
You can call the lexer's input/yyinput function to read characters from the input stream and do something with them (and they won't be tokenized so the parser will never see them).
You can use lexer states, putting the lexer in a different state where it will skip over the excluded text, rather than returning it as tokens.
The problem with either of the above from a parser action is dealing with the parser's one token lookahead, which occurs in some (but not all) cases. For example, the following will probably work:
external_code: EXT_CODE_START '{' { skip_external_code(); } '}'
as the action will be in a default reduction state with no lookahead. In this case, skip_external_code could either just set the lexer state (second option above), or it could call input until it gets to the matching } and then calls unput once (first option above).
Note that the skip_external_code function needs to be defined in the 3rd section of the the lexer file so it has access to static functions and macros in the lexer (which both of these techniques depend on).
For my diploma thesis I chose to implement the task of the ICFP 2004 contest.
The task--as I translated it to myself--is to write a compiler which translates a high-level ant-language into a low-level ant-assembly. In my case this means using a DSL written in Clojure (a Lisp dialect) as the high-level ant-language to produce ant-assembly.
UPDATE:
The ant-assembly has several restrictions: there are no assembly-instructions for calling functions (that is, I can't write CALL function1, param1), nor returning from functions, nor pushing return addresses onto a stack. Also, there is no stack at all (for passing parameters), nor any heap, or any kind of memory. The only thing I have is a GOTO/JUMP instruction.
Actually, the ant-assembly is for to describe the transitions of a state machine (=the ants' "brain"). For "function calls" (=state transitions) all I have is a JUMP/GOTO.
While not having anything like a stack, heap or a proper CALL instruction, I still would like to be able to call functions in the ant-assembly (by JUMPing to certain labels).
At several places I read that transforming my Clojure DSL function calls into continuation-passing style (CPS) I can avoid using the stack[1], and I can translate my ant-assembly function calls into plain JUMPs (or GOTOs). Which is exactly what I need, because in the ant-assembly I have no stack at all, only a GOTO instruction.
My problem is that after an ant-assembly function has finished, I have no way to tell the interpreter (which interprets the ant-assembly instructions) where to continue. Maybe an example helps:
The high-level Clojure DSL:
(defn search-for-food [cont]
(sense-food-here? ; a conditional w/ 2 branches
(pickup-food ; true branch, food was found
(go-home ; ***
(drop-food
(search-for-food cont))))
(move ; false branch, continue searching
(search-for-food cont))))
(defn run-away-from-enemy [cont]
(sense-enemy-here? ; a conditional w/ 2 branches
(go-home ; ***
(call-help-from-others cont))
(search-for-food cont)))
(defn go-home [cont]
(turn-backwards
; don't bother that this "while" is not in CPS now
(while (not (sense-home-here?))
(move)))
(cont))
The ant-assembly I'd like to produce from the go-home function is:
FUNCTION-GO-HOME:
turn left nextline
turn left nextline
turn left nextline ; now we turned backwards
SENSE-HOME:
sense here home WE-ARE-AT-HOME CONTINUE-MOVING
CONTINUE-MOVING:
move SENSE-HOME
WE-ARE-AT-HOME:
JUMP ???
FUNCTION-DROP-FOOD:
...
FUNCTION-CALL-HELP-FROM-OTHERS:
...
The syntax for the ant-asm instructions above:
turn direction which-line-to-jump
sense direction what jump-if-true jump-if-false
move which-line-to-jump
My problem is that I fail to find out what to write to the last line in the assembly (JUMP ???). Because--as you can see in the example--go-home can be invoked with two different continuations:
(go-home
(drop-food))
and
(go-home
(call-help-from-others))
After go-home has finished I'd like to call either drop-food or call-help-from-others. In assembly: after I arrived at home (=the WE-ARE-AT-HOME label) I'd like to jump either to the label FUNCTION-DROP-FOOD or to the FUNCTION-CALL-HELP-FROM-OTHERS.
How could I do that without a stack, without PUSHing the address of the next instruction (=FUNCTION-DROP-FOOD / FUNCTION-CALL-HELP-FROM-OTHERS) to the stack? My problem is that I don't understand how continuation-passing style (=no stack, only a GOTO/JUMP) could help me solving this problem.
(I can try to explain this again if the things above are incomprehensible.)
And huge thanks in advance for your help!
--
[1] "interpreting it requires no control stack or other unbounded temporary storage". Steele: Rabbit: a compiler for Scheme.
Yes, you've provided the precise motivation for continuation-passing style.
It looks like you've partially translated your code into continuation-passing-style, but not completely.
I would advise you to take a look at PLAI, but I can show you a bit of how your function would be transformed, assuming I can guess at clojure syntax, and mix in scheme's lambda.
(defn search-for-food [cont]
(sense-food-here? ; a conditional w/ 2 branches
(search-for-food
(lambda (r)
(drop-food r
(lambda (s)
(go-home s cont)))))
(search-for-food
(lambda (r)
(move r cont)))))
I'm a bit confused by the fact that you're searching for food whether or not you sense food here, and I find myself suspicious that either this is weird half-translated code, or just doesn't mean exactly what you think it means.
Hope this helps!
And really: go take a look at PLAI. The CPS transform is covered in good detail there, though there's a bunch of stuff for you to read first.
Your ant assembly language is not even Turing-complete. You said it has no memory, so how are you supposed to allocate the environments for your function calls? You can at most get it to accept regular languages and simulate finite automata: anything more complex requires memory. To be Turing-complete you'll need what amounts to a garbage-collected heap. To do everything you need to do to evaluate CPS terms you'll also need an indirect GOTO primitive. Function calls in CPS are basically (possibly indirect) GOTOs that provide parameter passing, and the parameters you pass require memory.
Clearly, your two basic options are to inline everything, with no "external" procedures (for extra credit look up the original meaning of "internal" and "external" here), or somehow "remember" where you need to go on "return" from a procedure "call" (where the return point does not necessarily need to fall in the physical locations immediately following the "calling" point). Basically, the return point identifier can be a code address, an index into a branch table, or even a character symbol -- it just needs to identify the return target relative to the called procedure.
The most obvious here would be to track, in your compiler, all of the return targets for a given call target, then, at the end of the called procedure, build a branch table (or branch ladder) to select from one of the several possible return targets. (In most cases there are only a handful of possible return targets, though for commonly used procedures there could be hundreds or thousands.) Then, at the call point, the caller needs to load a parameter with the index of its return point relative to the called procedure.
Obviously, if the callee in turn calls another procedure, the first return point identifier must be preserved somehow.
Continuation passing is, after all, just a more generalized form of a return address.
You might be interested in Andrew Appel's book Compiling with Continuations.