In Go, how to write a multi-line statement? - go

In python, we use backslash to indicate that the current statement continues to next line
for example,
a = b + c + s \
+ x + y
or simply,
a = b + c + s +
x + y
Is it possible to do that in Go language? Thanks

Sure it is, just put an operator at the end, for example:
a = b + c + s +
x + y
Also note that it's not possible to break the line before the operator. The following code is invalid:
a = b + c + s
+ x + y
The rule is described here and in the specification.

Interestingly, the the Go language specification itself requires semicolons at the end of each statement, but the lexer will insert implicit semicolons at the end of lines that look like statements immediately before compilation.
Therefore, to prevent the unwanted semicolon at the end of an unfinished line, all you need to do is ensure that the line doesn't end with something that could make it look like a complete statement.
In other words, avoid ending an incomplete line in a variable, constant, function, keyword, or postfix operator (e.g. ++).
What does that leave? Well, a few things come to mind -- an infix operator (e.g. = or +), a comma, or an opening paren or brace or bracket, for example.

Related

What does an 'at' # sign mean in Julia?

For example, here:
ys = lift(frequency, phase) do fr, ph
#. 0.3 * sin(fr * xs - ph)
end
from here.
I am failing to interpret it as a macro definition or call.
TLDR: # invokes a macro. https://docs.julialang.org/en/v1/manual/metaprogramming/
One of julia's best features in my opinion are it's macros. They allow you to easily write functions that manipulate source code. #. for example turns 0.3 * sin(fr * xs - ph) into 0.3 .* sin(fr .* xs - ph). Another common example is #time which roughly would translate the same expression to
t1=time()
0.3 * sin(fr * xs - ph)
println(time()-t1)
Note that neither of these are achievable by a function, since functions have their inputs evaluated before they run, while macros instead operate on the code itself.
I think it is worth to add that it is easy to learn what #. does by invoking help. Press ? then write #. and hit enter to get:
help?> #.
#. expr
Convert every function call or operator in expr into a "dot call" (e.g.
convert f(x) to f.(x)), and convert every assignment in expr to a "dot
assignment" (e.g. convert += to .+=).
If you want to avoid adding dots for selected function calls in expr, splice
those function calls in with $. For example, #. sqrt(abs($sort(x))) is
equivalent to sqrt.(abs.(sort(x))) (no dot for sort).
(#. is equivalent to a call to #__dot__.)
Examples
≡≡≡≡≡≡≡≡≡≡
julia> x = 1.0:3.0; y = similar(x);
julia> #. y = x + 3 * sin(x)
3-element Array{Float64,1}:
3.5244129544236893
4.727892280477045
3.4233600241796016
where you also learn that #. is just a shorthand for #__dot__.
And if you want to find its definition write e.g.:
julia> #which #. 1
#__dot__(__source__::LineNumberNode, __module__::Module, x) in Base.Broadcast at broadcast.jl:1241
to get the exact information on location of its implementation or write #edit #. 1 and it will get opened-up in your editor.
Above I have commented on how to learn what #. does and how it is implemented. If you want to learn what is the effect of #. (or any macro in general) you can use the #macroexpand macro. Therefore if you write e.g.:
julia> #macroexpand #. coalesce(sin(#view x[:, 1]), 0.0)
:(coalesce.(sin.(true && (view)(x, :, 1)), 0.0))
you can see how #. macro rewrites your original expression coalesce(sin(x), 0.0). Note that in this case the expressions are not evaluated - you only get an equivalent expression with all macros removed.
If you wanted to see only #. macro expanded (assuming - as in an example above it is the outermost macro) then use:
julia> #macroexpand1 #. coalesce(sin(#view x[:, 1]), 0.0)
:(coalesce.(sin.(#= REPL[11]:1 =# #view(x[:, 1])), 0.0))
As you can see #macroexpand1 is not recursive and only expanded the outermost macro and left #view macro untouched.

What does this variable notation mean ? a[++b]=$c

I have seen this notation in bash:
a=${b[c--]}
or also
a[++b]=$c
or the other way around:
a[b++]=$c
but if I execute it on the command line nothing happens.
OSX#26:~ $ a[++b]=2
OSX#27:~ $ echo ${a[++b]}
OSX#28:~ $
What is the use of this notation ?
Edit:
I am asking about this notation. As I have seen it it is a variable, because of the $ in front. But ++ does remind me of increment, so I am confused. Is this some sort of variable increment ?
c-- is an arithmetic expression, it means "return the value of c and then decrement it by 1". ${b[n]} denotes the n-th element of the array b (where the first element has index 0). Expressions inside the square brackets are interpreted as arithmetic (with some exceptions like *, #, '1' etc.) Let's try it:
b=(x y z)
c=2
a=${b[c--]}
echo $a $c # Outputs: z 1
so c-- returns 2, but sets c to 1. b[2], i.e. z, is then assigned to a.
++c is similar to c--, but it adds 1 to c before returning its value.

Understanding precedence of assignment and logical operator in Ruby

I can't understand precedence of Ruby operators in a following example:
x = 1 && y = 2
Since && has higher precedence than =, my understanding is that similarly to + and * operators:
1 + 2 * 3 + 4
which is resolved as
1 + (2 * 3) + 4
it should be equal to:
x = (1 && y) = 2
However, all Ruby sources (including internal syntax parser Ripper) parse this as
x = (1 && (y = 2))
Why?
EDIT [08.01.2016]
Let's focus on a subexpression: 1 && y = 2
According to precedence rules, we should try to parse it as:
(1 && y) = 2
which doesn't make sense because = requires a specific LHS (variable, constant, [] array item etc). But since (1 && y) is a correct expression, how should the parser deal with it?
I've tried consulting with Ruby's parse.y, but it's so spaghetti-like that I can't understand specific rules for assignment.
Simple. Ruby only interprets it in a way that makes sense. = is assignment. In your expectation:
x = (1 && y) = 2
it does not make sense to assign something to 1 && y. You can only assign something to a variable or a constant.
And note that the purpose of the precedence rule is to disambiguate an otherwise ambiguous expression. If one way to interpret it does not make sense, then there is no need for disambiguation, and hence the precedence rule would not be in effect.
My understanding is that in the case of
x = 1 && y = 2
The logical AND is parsed first. The AND then is forced to evaluate its left side and its right side. In the evaluation the left side the first assignment occurs, and then in the evaluation of the right side the second does the same. It is for this reason that in the case of:
x = false && y = 2
"y" will never be assigned. The AND is hit, forcing the x assignment to evaluate, but never bothering to run the y assignment, as it is unnecessary for the AND to fulfill its purpose.
In other words, the parser is, again, simply to my understanding, smart enough to recognize that in running the AND the equation is split into a left and right side (equations), which are in turn evaluated according to the order of operation.

Evaluation functions and expressions in Boolean expressions

I am aware how we can evaluate an expression after converting into Polish Notations. However I would like to know how I can evaluate something like this:
If a < b Then a + b Else a - b
a + b happens in case condition a < b is True, otherwise, if False a - b is computed.
The grammar is not an issue here. Since I only need the algorithm to solve this problem. I am able evaluate boolean and algebraic expressions. But how can I go about solving the above problem?
Do you need to assign a+b or a-b to something?
You can do this:
int c = a < b ? a+b : a-b;
Or
int sign = a < b ? 1 : -1;
int c = a + (sign * b);
Refer to LISP language for S-express:
e.g
(if (> a b) ; if-part
(+ a b) ; then-part
(- a b)) ; else-part
Actually if you want evaluate just this simple if statement, toknize it and evaluate it, but if you want to evaluate somehow more complicated things, like nested if then else, if with experssions, multiple else, variable assignments, types, ... you need to use some parser, like LR parsers. You can use e.g Lex&Yacc to write a good parser for your own language. They support somehow complicated grammars. But if you want to know how does LR parser (or so) works, you should read into them, and see how they use their table to read tokens and parse them. e.g take a look at wiki page and see how does LR parser table works (it's something more than simple stack and is not easy to describe it here).
If your problem is just really parsing if statement, you can cheat from parser techniques, you can add empty thing after a < b, which means some action, and empty thing after else, which also means an action. When you parsed the condition, depending on correctness or wrongness you will run one of actions. By the way if you want to parse expressions inside if statement you need conditional stack, means something like SLR table.
Basically, you need to build in support for a ternary operator. IE, where currently you pop an operator, and then wait for 2 sequential values before resolving it, you need to wait for 3 if your current operation is IF, and 2 for the other operations.
To handle the if statement, you can consider the if statement in terms of C++'s ternary operator. Which formats you want your grammar to support is up to you.
a < b ? a + b : a - b
You should be able to evaluate boolean operators on your stack the way you currently evaluate arithmetic operations, so a < b should be pushed as
< a b
The if can be represented by its own symbol on the stack, we can stick with '?'.
? < a b
and the 2 possible conditions to evaluate need to separated by another operator, might as well use ':'
? < a b : + a b - a b
So now when you pop '?', you see it is the operator that needs 3 values, so put it aside as you normally would, and continue to evaluate the stack until you have 3 values. The ':' operator should be a binary operator, that simply pushes both of its values back onto the stack.
Once you have 3 values on the stack, you evaluate ? as:
If the first value is 1, push the 2nd value, throw away the third.
If the first value is 0, throw away the 2nd and push the 3rd.

In Erlang, when do I use ; or , or .?

I have been trying to learn Erlang and have been running into some problems with ending lines in functions and case statements.
When do I use a semicolon (;), comma (,), or period inside my functions or case statements?
I like to read semicolon as OR, comma as AND, full stop as END. So
foo(X) when X > 0; X < 7 ->
Y = X * 2,
case Y of
12 -> bar;
_ -> ook
end;
foo(0) -> zero.
reads as
foo(X) when X > 0 *OR* X < 7 ->
Y = X * 2 *AND*
case Y of
12 -> bar *OR*
_ -> ok
end *OR*
foo(0) -> zero *END*
This should make it clear why there is no ; after the last clause of a case.
Comma at the end of a line of normal code.
Semicolon at the end of case statement, or if statement, etc.
The last case or if statement doesn't have anything at the end.
A period at the end of a function.
example (sorry for the random variable names, clearly this doesn't do anything, but illustrates a point):
case Something of
ok ->
R = 1, %% comma, end of a line inside a case
T = 2; %% semi colon, end of a case, but not the end of the last
error ->
P = 1, %% comma, end of a line inside a case
M = 2 %% nothing, end of the last case
end. %% period, assuming this is the end of the function, comma if not the end of the function
Period (.)
In modules, the period is used to terminate module attributes and function declarations (a.k.a. 'forms'). You can remember this because forms aren't expressions (no value is returned from them), and therefore the period represents the end of a statement.
Keep in mind that definitions of functions with different arities are considered separate statements, so each would be terminated by a period.
For example, the function definitions for hello/0 and hello/1:
hello() -> hello_world.
hello(Greeting) -> Greeting.
(Note that in the erlang shell the period is used to terminate and evaluate expressions, but that is an anomaly.)
Semicolon (;)
The semicolon acts as a clause separator, both for function clauses and expression branches.
Example 1, function clauses:
factorial(0) -> 1;
factorial(N) -> N * fac(N-1).
Example 2, expression branches:
if X < 0 -> negative;
X > 0 -> positive;
X == 0 -> zero
end
Comma (,)
The comma is an expression separator. If a comma follows an expression, it means there's another expression after it in the clause.
hello(Greeting, Name) ->
FullGreeting = Greeting ++ ", " ++ Name,
FullGreeting.
You can think of it like english punctuation. Commas are used to separate things in a series, semicolons are used to separate two very closely related independent clauses[1] (e.g. the different cases of the case statement, function clauses of the same name and arity that match different patterns), and periods are used to end a sentence (complete thought).
Or to prove you went to college. "Do not use semicolons. They are transvestite hermaphrodites representing absolutely nothing. All they do is show you've been to college." -- Kurt Vonnegut
The comma separates expressions, or arguments, or elements of a list/tuple or binary. It is overworked.

Resources