What are the scenarios , where = is preferred over := ?
What are the scenarios, where := is preferred over = ?
I read from gnu site, that usage of = makes make run slower. I just wonder, when do we use = in makefile?
To answer your question, = is used when you want to delay expansion of the right side until the variable is used.
This allows you to define variables in any order. It also allows you to create variables with values that refer to automatic variables (remember automatic variables have no value until the rule is being run). So for example:
my_FLAGS = -a
your_FLAGS = -b
FLAGS = $($#_FLAGS)
my your : ; #echo $(FLAGS)
this cannot work if you use := because when the FLAGS variable is defined, $# has no value.
They are also useful when defining user-defined functions that can later be invoked with $(call ...); you don't want those to be expanded until they are called.
With simply defined variables you can do things like recursively use the variable:
ITEMS := one two three
ITEMS := $(addsuffix $(ITEMS))
This is because the simple assignment (:=) happens in the order you read them
Non simple assignment (=) is recursively expanded so if you assign it to other variables they are in turn expanded until you end up with the final result that contains all the expanded parts. Note that the makefile first parses the file so that the order you do the assignment is not so important, examples to follow:
i.e. this is not allowed:
ITEMS = one two three
ITEMS = $(addsuffix $(ITEMS))
So this affects when you want to use each type. With non simple you can do:
ITEMS1 = a b c
ITEMS_all = $(ITEMS1) $(ITEMS2)
ITEMS2 = d e f
And now ITEMS_ALL will contain a b c d e f - even though they are not defined in order, this can be very useful. So if you just want to assign a simply value - stick with := if you want to keep adding things to a variable you might want to use =...
Related
I was wondering if there's a way with Go to declare and initialise multiple variables of different types in one line without using the short declaration syntax :=.
Declaring for example two variables of the same type is possible:
var a, b string = "hello", "world"
Declaring variables of different types with the := syntax is also possible:
c, d, e := 1, 2, "whatever"
This gives me an error instead:
var f int, g string = 1, "test"
Of course I'd like to keep the type otherwise I can just use the := syntax.
Unfortunately I couldn't find any examples so I'm assuming this is just not possible?
If not, anyone knows if there's a plan to introduce such syntax in future releases?
It's possible if you omit the type:
var i, s = 2, "hi"
fmt.Println(i, s)
Output (try it on the Go Playground):
2 hi
Note that the short variable declaration is exactly a shorthand for this:
A short variable declaration uses the syntax:
ShortVarDecl = IdentifierList ":=" ExpressionList .
It is shorthand for a regular variable declaration with initializer expressions but no types:
"var" IdentifierList = ExpressionList .
Without omitting the type it's not possible, because the syntax of the variable declaration is:
VarSpec = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) .
(There is only one optional type for an identifier list with an expression list.)
Also I assume you don't count this as 1 line (which otherwise is valid syntax, but gofmt breaks it into multiple lines):
var (i int = 2; s string = "hi")
Also if you only want to be able to explicitly state the types, you may provide them on the right side:
var i, s = int(2), string("hi")
But all in all, just use 2 lines for 2 different types, nothing to lose, readability to win.
This isn't exactly specific to the OP's question, but since it gets to appear in search results for declaring multiple vars in a single line (which isn't possible at the moment). A cleaner way for that is:
var (
n []int
m string
v reflect.Value
)
This is a quote from make's docs about the call function:
The call function can be nested. Each recursive invocation gets its own local values for $(1), etc. that mask the values of higher-level call. Here is an implementation of a map function:
map = $(foreach a,$(2),$(call $(1),$(a)))
Now it can map a function that normally takes only one argument, such as origin, to multiple values in one step:
o = $(call map,origin,o map MAKE)
and end up with o containing something like ‘file file default’.
Can somebody take the pain to explain what are they trying to convey and explain the code:
o = $(call map,origin,o map MAKE)
When programming in Ruby I quite often have assignments like the following
test = some_function if some_function
With that assignments I want to assign the output of a function, but if it returns nil I want to keep the content of the variable. I know there are conditional assignments, but neither ||= nor &&= can be used here. The shortest way I found to describe the statement above is
test = (some_function or test)
Is there a better / shorter way to do this?
I don't think there's anything better than the last snippet you showed but note that or is used for flow control, use || instead:
test = some_function || test
It's usually better to assign new values to new names, the resulting code is easier to understand and debug since variables/symbols have the same value throughout the scope:
some_different_and_descriptive_name_here = some_function || test
I'd just add parentheses
(a = b) unless b.nil?
(a = b) if b
being inferior because if b is false then a remains as before
Keep in mind that this evaluates b twice, so if b is a function with side-effects (such as changing variables outside of its scope or printing) it will do that twice; to avoid this you must use
temp = b; (a = temp) unless temp.nil?
(which can, of course, be split into)
temp = b
(a = temp) unless temp.nil?
As noted elsewhere, you can list all user-defined symbols with this:
Names["Global`*"]
But I'd like to find just my global variables (I'm in the middle of some hairy debugging), not my function definitions. Something like this is close:
Select[Names["Global`*"], Head#Symbol[#]=!=Symbol && Head#Symbol[#]=!=Function&]
But that misses variables whose value is a symbol (perhaps I have x = Pi).
I could probably beat that thing into submission but maybe there's a cleaner, more direct way?
If we consider any symbol with an own-value as a "variable", then this will do the trick:
ClearAll[variableQ]
variableQ[name_String] := {} =!= ToExpression[name, InputForm, OwnValues]
Select[Names["Global`*"], variableQ]
Note that this technique will fail on read-protected symbols and will misidentify some forms of auto-loaded functions.
Edit 1
As #Szabolcs points out, the definition of variableQ can be simplified if ValueQ is used:
variableQ[name_String] := ToExpression[name, InputForm, ValueQ]
Edit 2
As #dreeves points out, it might be desirable to filter out apparent variables whose values are functions, e.g. f = (#+1)&:
variableQ[name_String] :=
MatchQ[
ToExpression[name, InputForm, OwnValues]
, Except[{} | {_ :> (Function|CompiledFunction)[___]}]
]
This definition could be easily extended to check for other function-like forms such as interpolating functions, auto-loaded symbols, etc.
One might consider a variable to be a Global` symbol that does not pass FunctionQ.
I want to define a symbol and use it within a function. For example, with IDnumbers defined as a list of numbers:
ParallelMap[{#1, Name[#1], Age[#1]} &, IDnumbers]
With userlist={#1, Name[#1], Age[#1]} becomes:
ParallelMap[userlist &, IDnumbers]
It works just fine with the list itself in the code, but not with the symbol. The same thing happens with a list of strings vs. a symbol assigned to a list of strings. Why is this?
Since f[#]& is shorthand for Function[f[#]] you should always complete your anonymous function with a trailing & to get a working function.
In your example:
userlist={#1, Name[#1], Age[#1]}&
ParallelMap[userlist, IDnumbers]
More thorough explanation:
By just using something like f[#] you get (in FullForm[])
In[15] := f[#] // FullForm
Out[15]//FullForm = f[Slot[1]]
whereas this gets transformed to a Function by the trailing & operator:
In[16] := f[#]& // FullForm
Out[16]//FullForm = Function[f[Slot[1]]]
If you do this in two steps, & doesn't evaluate the intermediate variable expr:
In[25]:= expr = f[#]//FullForm
In[26]:= expr &
Out[25]//FullForm = f[Slot[1]]
Out[26] = expr &
You can force the evaluation of expr before it gets wrapped in the Function[] by using Evaluate[]:
In[27]:= expr=f[#]//FullForm
In[28]:= Evaluate[expr]&
Out[27]//FullForm = f[Slot[1]]
Out[28] = f[Slot[1]]&
Another way is to supply the Function[] wrapper yourself:
userlist={#1, Name[#1], Age[#1]}
ParallelMap[Function[userlist], IDnumbers]
Personally, i would consider this bad coding style. Just get used to always finishing an anonymous function with a trailing & like you would supply a closing paranthesis ) to a corresponding opening one (.
Edit
Ok, in your case of a dynamically generated anonymous function i can see why you couldn't supply the & directly. Just wrap the expression with the Slot[]s in a Function[] instead.