I had a look at twitter bootstrap mixin.less where they generate the grid. There's this line of code:
.offsetX (#index) when (#index > 0) {
(~".offset#{index}") { .offset(#index); }
.offsetX(#index - 1);
}
.offsetX (0) {}
Does anyone know what does that .offsetX (0) for?
Since .offsetX (#index) is recursive when the index is greater than 0, and iterates by subtraction, this case represents the terminal point of the recursive function.
If you set #index to 12, it will write .offset12, .offset11,..., .offset1 and write nothing for .offset0.
Edit
As the preprocessor attempts to resolve the mixin call for .offsetX (0), the when keyword is going to guard against using the recursive mixin. If another mixin isn't found, an error will result, sort of like calling an undefined function.
Hence, the terminating case of .offset (0) {} is there to cleanly exit the recursion.
If you'd like to play with it, here's a basic demo with which you can try commenting out the line with the terminal case, and then observe the exception on rerunning.
JSFiddle
Related
I write my if {...} else {...} statement in R in the following way as I find it more readable.
Testifelse = function(number1)
{
if(number1>1 & number1<=5)
{
number1 =1
}
else if ((number1>5 & number1 < 10))
{
number1 =2
}
else
{
number1 =3
}
return(number1)
}
According to ?Control:
... In particular, you should not have a newline between } and else to avoid a syntax error in entering a if ... else construct at the keyboard or via source ...
the function above will cause syntax error, but actually it works! What's going on here?
Thanks for your help.
Original question and answer
If we put in R console:
if (1 > 0) {
cat("1\n");
}
else {
cat("0\n");
}
why does it not work?
R is an interpreted language, so R code is parsed line by line. (Remark by #JohnColeman: This judgement is too broad. Any modern interpreter does some parsing, and an interpreted language like Python has no problem analogous to R's problem here. It is a design decision that the makers of R made, but it wasn't a decision that was forced on them in virtue of the fact that it is interpreted (though doubtless it made the interpreter somewhat easier to write).)
Since
if (1 > 0) {
cat("1\n");
}
makes a complete, legal statement, the parser will treat it as a complete code block. Then, the following
else {
cat("0\n");
}
will run into error, as it is seen as a new code block, while there is no control statement starting with else.
Therefore, we really should do:
if (1 > 0) {
cat("1\n");
} else {
cat("0\n");
}
so that the parser will have no difficulty in identifying them as a whole block.
In compiled language like C, there is no such issue. Because at compilation time, the compiler can "see" all lines of your code.
Final update related to what's going on inside a function
There is really no magic here! The key is the use of {} to manually indicate a code block. We all know that in R,
{statement_1; statement_2; ...; statement_n;}
is treated as a single expression, whose value is statement_n.
Now, let's do:
{
if (1 > 0) {
cat("1\n");
}
else {
cat("0\n");
}
}
It works and prints 1.
Here, the outer {} is a hint to the parser that everything inside is a single expression, so parsing and interpreting should not terminate till reaching the final }. This is exactly what happens in a function, as a function body has {}.
This code works:
void reverse(char *str)
{
if(*str)
{
reverse(str+1);
printf("%c", *str);
}
}
But, if i change reverse(str+1) with reverse(++str), it doesn't print first character.
In: Geeks
Out: skee
I don't know why.
Because you're altering the pointer given to you in the very first call of the method, so when it finally gets around to printing itself out and completing the execution, the index has already been incremented to the second character.
In the first case, str+1, str isn't being modified at all, so the very last printf just prints the first character.
Keep in mind that the prefix and postfix ++ actually change the value of the variable.
++str increments first then prints, you need str++
I using the less mixin which generate a random number within given range.
here is the code:
.makeRandom(#min: 0, #max: #min+1) {
// Math.floor(Math.random() * (max - min + 1)) + min
#getNum: `(Math.floor(Math.random() * (#{max} - #{min} + 1)) + #{min})`;
}
and Calling in another mixin set animation on calling div:
.move (#left : 45% , #duration: 5s ,#delay : 2s) {
animation: moveUp #duration linear #delay infinite;
/* Safari and Chrome: */
-webkit-animation: moveUp #duration linear #delay infinite ;
.makeRandom(100, 400);
margin-left: unit(#getNum ,'px');
}
but I am getting this error
SyntaxError: error evaluating function unit: the first argument to unit must be a number
when I tried to change the unit. how can I changed unit of #getnum?
I noticed this problem in v1.5.
Since v1.5 you can not pass non-numeric values (not passing isnumber()) to functions like unit() that accept only numbers as arguments, even though it worked in earlier versions.
And - numeric values in javascript interpolation were not recognized as numeric by LESS <= 1.6.0, and isnumber(`2`); would have returned false.
So, this two put together are the reason why numbers returned by javascript did not work in v1.5, but worked prior v1.5 and work again in LESS v1.6.
But if you need to use it in 1.5 you can "cast the type" by using a function that does accept strings or the "non-numeric numbers" returned by javascript interpolation:
#str: '230'; //or `230`
#getNum: (percentage(#str)/100);
this adds the percentage sign % at the end ... but it does not really matter if you just want to use it for the number ... as now you can pass it to any function that accepts only numbers ... in your case using unit() you can change the unit to whatever you like.
margin-left: unit(#getNum , px);
However, an even simpler solution in your case would be to just skip the unit() function and concatenate the unit to #getNum:
margin-left: ~'#{getNum}px';
The CSS output would in both cases look like this:
margin-left: 230px;
I'm not sure if it was your case too, but since I landed on this page looking for an answer to the same error about 4 years later I decided to post this here so that it might help someone else in the same predicament 😊.
So, in our case we were getting this error in expressions like this:
width: unit(#navbarHeight - 0.1, em);
And the solution was to simply enclose the mathematical expression (in this case, subtraction) in parentheses, like this:
width: unit((#navbarHeight - 0.1), em);
#AsGoodAsItGets is right, as stated in the 4.0 changelog.
Parentheses are required (by default) around division-like expressions, to force math evaluation.
I am trying to make a variadic mixin in LESS. To this end I use the following syntax for my mixin :
.mixin (#a; #rest...) {
// #rest is bound to arguments after #a
// #arguments is bound to all arguments
}
But I don't know how to manipulate #rest and read to the last parameters of the mixin.
This is my code :
.color () { }
.color (#shade) {
#id {
background-color : rgb(#shade, #shade, #shade);
}
}
.color (#shade, #rest...) {
#id {
background-color : rgb(#shade, #shade, #shade);
}
.color(#rest);
}
.color(200, 160);
As you guess, this mixin should examinate the entire list of parameters, and colour the background of my <div id="id"> with the shade of grey corresponding to the last parameter of the mixin (in this case, rgb(160, 160, 160)).
But when I compile this code with less-1.4.1.js, I get the following error :
SyntaxError: error evaluating function `rgb`:
color functions take numbers as parameters
So how to access to the second, third, fourth... parameters of the mixin ?
Thanks a lot for your advices, and have a nice week-end !
EDIT
This works perfectly, thanks a lot !
However I would like to ask an other question. Let's say that my mixin is variadic to the extent that it requires at least one parameter which has nothing to do with the rest of the arguments (e.g. a string or an other number), but which has to be processed, so that possible calls to the previous mixin could be :
.color("first argument", 200, 160);
.color(-42, 200, 160);
.color(3, 200, 160); // 3 doesn't need to be processed in the loop
In other words, the .loop should examinate all the parameters of the mixin starting from the second and apply a different process to the first argument. So I need to change the skeleton of the mixin into something like this :
.color(...) {
...; // Handling the first parameter
.loop (#arguments); // Handling the rest of the parameters
}
But in your solution, the variable #arguments contains the entire list of arguments, including the first. How to exclude it from the list, without playing on isnumber() ?
I precise that actually in my project, each of the parameters starting from the second are processed, so that :
.loop(#list, #index: 1, #shade: NULL) when not (isnumber(#list)) and (isnumber(extract(#list, #index))) {
.loop(#list, (#index + 1), extract(#list, #index));
}
becomes
.loop(#list, #index: 1, #shade: NULL) when not (isnumber(#list)) and (isnumber(extract(#list, #index))) {
.loop(#shade);
.loop(#list, (#index + 1), extract(#list, #index));
}
and this process doesn't consist in simply changing the background color of a fixed <div> ;) But I wanted to simplify my question.
Thanks a lot for your answers and precious advices !
Edit, again : what you recommend to me works perfectly, Martin. Thanks again !
Less gets confused with your second and third .color mixin, as they can both take just one argument, and if #rest is passed to the mixin as an argument and is not numeric (i.e. a list or empty) it causes more problems. Also #rest... and ... are tricky with multiple mixins with the same name - it is better to pass the arguments to another set of mixins (as a list to a single argument) and then switch between them using guards or the number of arguments they can take.
I would structure the mixins a bit differently (and add a helper mixin .loop that does the looping according to what is passed to .color).
The two mixins would then work like this:
.color: passes all arguments in #arguments to a single argument in mixin .loop
.loop: if the argument is neither a list nor a numeric value -> no output
.loop: if multiple arguments in a list -> loop through the list until you reach the last numeric value (or rather stops when it meets the first nonnumeric argument)
.loop: when reached the last parameter return output based on its value
.loop: if parameter is a single value -> return output based on the single parameter
in Less this could be done like this:
.loop(#list, #index: 1, #shade: NULL) when not (isnumber(#list)) and not (isnumber(extract(#list, #index))) and not (isnumber(#shade)) {}
.loop(#list, #index: 1, #shade: NULL) when not (isnumber(#list)) and (isnumber(extract(#list, #index))) {
.loop(#list, (#index + 1), extract(#list, #index));
}
.loop(#list, #index: 1, #shade) when not (isnumber(#list)) and not (isnumber(extract(#list, #index))) {
.loop(#shade);
}
.loop(#shade) when (isnumber(#shade)){
#id {
background-color: rgb(#shade, #shade, #shade);
}
}
.color (...) {
.loop(#arguments);
}
and if you call now something like this:
.color(120,160);
the output CSS will look like this:
#id {
background-color: #a0a0a0;
}
which corresponds to the value of the last argument -> rgb(160,160,160)
This now has an output only for the last argument in the list. If you want to do something for each argument, you do so in the second .loop mixin (the actual loop) and can get rid of the third one that is used only to separate the last iteration step from the rest of the loop.
Edit:
To your additional question "How to deal differently with certain arguments and what to do when they are not numeric?" - > General answer: you can always adjust the guards, and add additional mixins for the specific cases.
For example, if you want to treat the first argument (or any argument) differently using the .loop, you can add an additional .loop mixin - like this:
.loop(#list) when not (isnumber(#list)) {
/* do something with the first argument */
#first_argument: extract(#list, 1);
/* start the loop at the second argument:*/
.loop(#list, 2);
}
with the rest left as is, this should do what you want:
save your "first argument" from the #arguments into a variable (or you can do with it whatever you want)
start the loop at the second argument and continue until it reaches the last numeric argument (as shown above)
As said before, this is just an example illustrating how to do what you asked ... but you will have to play with it and design the guards and mixins accordingly to your desired outcome and your specific problems.
In the loop you can do something to each argument ... and you can do different things to numeric and nonnumeric arguments (you just need to adjust the conditions in the guards), you can check also if the arguments have specific units and so on. All this is simple as you are merely iterating through a list using the extract() function and incrising the #index variable.
In the case the first argument / first couple arguments have a specific assignment you can use #rest in the same way as I show with #arguments and do something with the first argument already in the .color mixin before you send the #rest to the .loop. You would do something like this:
.color (#first, #rest...) {
/* do something with the first argument */
#first_argument: #first;
/* send the rest to the loop */
.loop(#rest);
}
I have a verilog code where I wish to use recursion. However, whenever I try this in an always block, it gives an error saying is not a task.
Is there any way I can implement a module in an always block? Also is there anyway I can use recursion within the always block?
You can write recursive modules using a generate block:
module unary_and
#(parameter WIDTH = 32)
(input [WIDTH-1:0] in_and,
output out_and)
generate
if(WIDTH == 1) begin
assign out_and = in_and;
end
else if(WIDTH == 2) begin
assign out_and = in_and[0] & in_and[1];
end
else begin
unary_and #(.WIDTH (WIDTH/2))
unary_and_low
(.in_and (in_and[WIDTH/2-1:0]),
.out_and (out_and_low));
unary_and #(.WIDTH (WIDTH - WIDTH/2))
unary_and_high
(.in_and (in_and[WIDTH-1:WIDTH/2]),
.out_and (out_and_high));
assign out_and = out_and_low & out_and_high;
end
endgenerate
endmodule
This is from Recursive and Iterative designs in Verilog where you can find other solutions as well. You can check out Recursive Modules too.
Maybe you should also take a look at these questions and answers:
Could we have generate inside an always block?
Verilog generate/genvar in an always block