Do symbols beginning with & have a special meaning? - syntax

What do &form and &env do in this example (taken from core.clj)?
(def
^{:macro true
:added "1.0"}
let (fn* let [&form &env & decl] (cons 'let* decl)))
Do symbols beginning with &... (other than just plain &) have special meaning in any contexts?
Why aren't &form and &env used in the body of the fn* form?

Yes, &form and &env are special variables within a macro. The names begin with '&' to avoid name clashes with normal user-defined symbols.
The value of &form is the form of the original macro call before macro expansion.
The value of &env is a map of lexical bindings. The keys of &env are the lexically bound symbols.
[adapted from stevenminer's comment]

Related

What does the ' represent in '+ in racket?

I have been banging around on google and drRacket trying to understand what the apostrophe ' before a procedure means in racket and how I could remove it. What I'm trying to do is take a + from inside a list i.e. '(+ 1 2). However, every time I do something like (first x) (where x is the list in the example) I receive '+ instead of just + (notice the apostrophe). How can I remove the apostrophe and what is its purpose?
The ' apostrophe, pronounced quote, mean that the stuff inside will be interpreted as data for an s-expression, not evaluated as code.
'x, 'hello, and '+ are all symbols, which are like strings with unique-identity properties. They contain only text, not "meaning", so the '+ symbol does not contain a reference to the + function.
If you use parentheses under a ' quote, it will create a list with all the elements also ' quoted. In other words, '(x y z) is equivalent to (list 'x 'y 'z). You can think of this as quote "distributing itself" over all the elements inside it.
In your case, '(+ 1 2) is equivalent to (list '+ '1 '2), which is the same as (list '+ 1 2) because numbers are already literal data.
In most cases, the best way to get rid of a ' quote is to not add one on the outside in the first place. Instead of '(+ 1 2) you could use list: (list + 1 2), or the more advanced forms ` quasiquote and , unquote: `(,+ 1 2). In either of these cases, the + never gets put under a quote in the first place. It never becomes a symbol like '+. The + outside of any quote has meaning as the addition function.
In other cases, you can't avoid having the symbol '+ because it comes from intrinsically textual data. In this case you can assign meaning to it with an interpreter. Somewhere in that interpreter you might want code like this
(match sym ['+ +] ['- -] ['* *] ['/ /] [_ (error "unrecognized symbol")])
Something is needed to assign meaning externally, because the symbol '+ does not have that meaning internally. You can either define the interpreter yourself or use an existing one such as eval, as long as all the meanings in the interpreter correspond exactly to what you intend.

let: bad syntax (not an identifier and expression for a binding) in: wordslist ###scheme

(define (most-common-word str)
(let (wordslist str-split str " ")))
I am trying to do a inner variable of lists of strings.
but I get the error "bad syntax".
I looked for answers here but the things I changed, didn't help.
str-split returns a list of strings with " " the separator.
thanks.
It should look like:
(let ([word-list <VALUE>]) <BODY>)
... which establishes a local binding from word-list to the value <VALUE>. This binding is effective only inside the <BODY> form enclosed by the let.
Now, in order to compute <VALUE>, you have to call str-split with the arguments you want (i.e. str and " "). The way you perform a function call is to wrap it in parenthesis (this is valid only in a context where the form is evaluated as an expression, not where parenthesis mean binding, for example). So <VALUE> should really be:
(str-split str " ")

How can I use C-style macros with C++11-style constructor calls?

I've found what seems to be an incompatibility between using C-style macros and using the new unified list-initialization form introduced in C++11, but it seems incredible that this sort of thing would be absolutely impossible to write, so I assume I'm missing something.
Here's the issue: curly brackets seem to be ignored when the preprocessor looks to find a macros arguments. A call like MACR(Range{2,4}) is misinterpreted as having two arguments, Range{2 and 4. In the following code, it's all good (well, poor style, but it works) until the marked line:
#include <iostream>
using namespace std;
struct Range { int st, fn; };
ostream& operator << (ostream& out, const Range& r)
{ return out << "(" << r.st << "," << r.fn << ")"; }
#define COUT(X) (cout << (X) << endl)
int main()
{
COUT(3);
Range r {3,5};
COUT(r);
COUT(Range{3,5}); //this line won't compile
}
It gives the following error message:
badmacro.cpp:16:18: error: macro "COUT" passed 2 arguments, but takes just 1
COUT(Range{3,5});
^
compilation terminated due to -Wfatal-errors.
Especially when working with older libraries, it's sometimes unavoidable to use macro calls; surely we're not supposed to forgo the new syntax in those cases? Is there an official workaround for this?
If you need to pass an expression to an existing macro, and an expression contains unshielded commas, just enclose the whole expression in parentheses.
COUT((Range{3,5}));
Ugly? Yes, but that's what happens when you are using macros. Don't do that.
If it's not an expression and can't take extra parentheses, then you simply can't use that macro.
If you are writing a macro, which you shouldn't, sometimes you can write a variadic macro (if your compiler supports that):
#define COUT(...) cout << (__VA_ARGS__) << endl;
Preprocessor macros are just fancy text replacements prior to compiling. When calling a macro, the preprocessor does very little parsing of the parameter list. There is some logic to differentiate between commas inside of nested parenthesis versus outside, so it knows which commas belong to the parameter list of the macro itself versus commas for the parameter list of a nested function call. For example:
macro(param1, param2, func(param1, param2) )
The parameters are interpreted as
param1
param2
func(param1, param2)
Rather than
param1
param2
func(param1
param2)
In your case, your comma is not inside of nested parenthesis, so the preprocessor ends up splitting the parameter list Range{3,5} into two parameter values
Range{3
5}
Hence the error because your macro only accepts one parameter. The preprocessor does not have any context information to know that Range{3,5} should be treated as one parameter value. It just sees the comma and splits on it.
So, to solve your problem, try adding an extra pair of parenthesis:
COUT((Range{3,5}));
The preprocessor should then interpret one parameter value:
(Range{3,5})
Which will create the following statement for the compiler to consume:
(cout << ((Range{3,5})) << endl);

Why do programmers put spaces inside braces?

In my experience, it's common to see spaces put inside braces for one-line definitions, e.g. this function in JavaScript:
function(a, b) { return a * b; }
Is there any technical/historical reason that most programmers seem to do this, particularly given that spaces are not included inside parentheses?
Besides readability, in some languages, such as Verilog, identifiers can be escaped (by a \ at their beginning) so that they use special characters in their names. For example, the following names are legal identifier names in Verilog:
q
\q~ //escaped version which uses ~ in the name
\element[32] //a single variable (not part of an array) whose name is \element[32]
Such identifiers, should always terminate by space, otherwise the character after them would be considered as the identifier's name:
{ d, \q~ } // Concatenating d and \q~ in a vector
{ d, \q~} // Concatenating d and \q~} in a vector. Will generate a missing brace error.
Spaces are mostly used for readability. Most of the coding styles will tell you to judiciously use whitespace in your code to make it more readable.
As an example, look at this statement: *a = *b + *c;. Think how it will seem without the whitespace.

Semantics of F# let statement with comma

I'm learning F#. I started by looking over the F# samples from Microsoft.
I ran across this statement:
let line1,line2 =
use sr = System.IO.File.OpenText #"test.txt"
let line1 = sr.ReadLine()
let line2 = sr.ReadLine()
(line1,line2)
Can anyone explain this statement to me?
What type is being defined here? A function? A tuple?
Why do line1 and line2 have to be redefined within the definition of line1,line2 (let line1 = ... let line2 =)?
What's with the final line, (line1, line2) and how does this tie into the type of the original definition? Is this the function return?
Is "statement" even the right word to use for a definition in F#?
Thanks.
The general form for binding identifier values in F# is
let pattern = expression
In this case, the pattern is "line1, line2", which is a tuple pattern, it will expect to bind to a 2-tuple of values and assign the names "line1" and "line2" to those two values.
The expression is the next 4 lines. Inside that expression there are local variables. They happen to also be named "line1" and "line2", but they could easily have been renamed "x" and "y" or whatever - the scope of those identifiers is local to this indented expression. (The fact that the same names are used as the names in the outer scope has no effect as far as the compiler is concerned.)
The final line if the expression is the 'return value' of the expression. In this case it returns the 2-tuple of values "line1" and "line2" (or "x" and "y" if you rename them for clarity of exposition). Incidentally, since these two values each have type "string", the type of the return expression is "string*string", which is a 2-tuple where each value is a string. This means the original "line1" and "line2" names on the first line will each be inferred to have type "string".
F# is functional, and so in a sense "everything is an expression" and "there are no statements" (only sequences of expressions that are sequentially evaluated), but it is ok IMO to (ab)use the term "statement" to describe the inner "let" lines, unless you're trying to be very precise.

Resources