I'd like a little clarification on the precedence of the return
statement, which appears to go against the general precedence
rules.
For example the expression
^ 2 + 3.
returns 5(which is what I want) but shouldn't it return just 2 since Unary operators
of which ^ is one has higher precedence over + which is Binary?.
There are no "unary operators" in Smalltalk. There are only 3 precedence levels: unary messages ("receiver message"), binary operators ("receiver + argument"), and n-ary keyword messages ("receiver message: argument1"). In all cases the receiver comes first.
So "^" is not an operator, but indicates a return statement. Similarly, in "-4" the "-" is not an operator but part of the number literal.
The return symbol, ^, is one of the few language built-ins constructs. Smalltalk will return the value of the expression following the ^ symbol.
Is Smalltalk's ^ really an operator at all ? I guess it is rather a reserved symbol. And what should happen to the "dangling" + 3 then, when the surrounding method has returned? I think the behavior is correct as the return statement is the last statement to happen in a "normal" Smalltalk method.
Regards
Related
I just started learning Smalltalk at uni.
I would like to know the difference between the messages & and and: (just like | and or:)
Welcome to Smalltalk! You are asking a good question that points out some subtle differences in expressions that are outside or inside blocks.
The '&' message is a "binary" message so takes only one argument. In this case the argument is expected to be a Boolean or an expression that evaluates to a Boolean. Most importantly for our purposes in this comparison, the expression will always be evaluated.
The 'and:' message is a "keyword" message and also takes only one argument. But in this case the argument is expected to be a Block that if later sent the 'value' message would return a Boolean. So, for our purposes in this comparison, the Block will not always be evaluated. (The difference between the binary and keyword messages does not matter for this question.)
The option to not evaluate the argument allows Short-circuit evaluation in which knowing the left-hand side often allows us to avoid a (possibly expensive) calculation of the right-hand side. So, if the left ("receiver") is false, there is nothing to be gained by evaluating the right-hand side.
So, consider the following:
self cheapFalse & self expensiveTrue. "an expensive way to get false"
self cheapFalse and: [self expensiveTrue]. "a cheap way to get false"
One obvious difference is that and: is a keyword message thus you can write something like
a > b and: [b < c]
while with & you would need parentheses in this expression:
a > b & (b < c)
because all the binary messages (+, -, >, <, &, |) have the same precedence.
More importantly, and: and or: expect blocks while & and | expect values. This means that you can write
this shouldRedraw and: [ obj stateChanged ]
where obj stateChanged will be executed only if this shouldRedraw is true. This is useful if you want to optimize your code and avoid computing something which is not needed at the moment.
I used an || operator within the Kotlin IDEA but was throwing an error. This confused me, one of the first queries when searching google was a closed stack overflow thread with a snarky "answer" comment which wasn't helpful.
The first query in google hit is some function "or" gibberish.
My code:
if(inputAmount >= 0 || inputAmount = -99)
I understand what is "wrong". there was some logic errors the second part of the "if" statement should have been inputAmount == -99. In my case, the code needed to further be adjusted because of the actual type that was being used.
if(inputAmount >= 0.0 || inputAmount.toInt() == -99)
This appears to be different then other languages in that other languages just simply allow you to have your "logic" error with the "inputAmount = -99". So the '||' operator is allowed and is similar to most other languages.
So first step if encounter this error is to make sure your logic is correct. (check)
infix functions > sense according to the documentation "or" and "and" are infix functions that don't use the short circuit, is it technically wrong to call the "||" operator an "or" operator and should be called logical 'or'?
when referring to the infix 'or' how do people refer to that in Kotlin?
in boolean logic takes statements. A=b is a statement that is always true
No, it isn't. In C, C++ and Java it's an expression, and its value is the value of b. If b is false, it's false, if b is 10, it's 10. And you really don't want to confuse "statements" in programming languages with "statements" in logic; they are entirely different things.
Separately, C and C++ (but not Java) allow || to work on all integral types, and not just booleans (because they didn't originally have booleans as a separate type).
when referring to the infix function 'or' how do Kotlin folk typically refer to that?
Bitwise or for integral types, and I've never actually seen anyone use non-short-circuiting or on booleans, but if I had to I'd call it... well, non-short-circuiting or.
is it technically wrong to call the "||" operator an "or" operator and should be called logical 'or'
Both || and or (on booleans) are "logical 'or'" and I don't see any problem with calling them simply 'or'. If you need to distinguish use short-circuiting vs non-short-circuiting. But again, I've never actually ran into a use of the non-short-circuiting version.
I'm fairly new to Visual Basic (my background is mostly C#) so I only recently found out that ++i is not the same thing as i+=1 in VB.NET. However, my VB.NET code still compiles when I pass ++i as a parameter, even though it doesn't increment the variable:
++i 'doesn't compile
i++ 'doesn't compile
Foobar(i++) 'doesn't compile
Foobar(++i) 'compiles, but doesn't increment i
The fact that the last statement above doesn't cause an error leads me to wonder if ++ actually does mean something in VB.NET, just not what I thought it meant at first. If it doesn't, is there some other reason it isn't causing an error?
It is just the unary version of the + operator (see docs) applied twice.
Foobar(++i)
Foobar(+(+i))
Foobar(+(+(i)))
' These are all the same
For numerical values, the unary + (i.e. the + operator without second operand) does nothing:
If expression2 is absent, the + operator is the unary identity operator for the unchanged value of an expression.
However, it is not entirely clear from the docs what it will do to non-numeric values. The docs explain various cases with two operands, which all don't seem to apply here.
There is even one sentence that sounds like it could be applied, but it does not do what it says if used with unary +:
If either Object expression evaluates to Nothing or DBNull, the + operator treats it as a String with a value of "".
So you would expect that +Nothing gives "" as well, but it gives 0 instead. In fact, it appears that the unary + converts non-numerical types to Double, including strings for which + would otherwise mean concatenation (for example +"1.234" gives 1.234, and +"Hello" gives an error that this string cannot be converted to Double - and with Option Strict On, you can't convert any string implicitly anyway). It seems to behave more like a binary + with 0.0 as first operand.
You can also overload the unary + separately from the binary + and give it a different meaning entirely*. (Or do the opposite - make it do nothing even on a non-numeric type, such as what TimeSpan does - it returns the original timespan again when unary + is applied on it, and not a Double.)
*: Which probably is not such a good idea though. When overloading an operator, the meaning of it should always be intuitive.
There is no ++ operator in VB. The + unary operator is just like the - unary operator applied to a number. Numbers are positive by default but, just as you can explicitly make a number negative by prefixing it with a - operator, you can make it explicitly positive by prefixing it with a + operator. You can use as many + operators as you like. Similarly, you can use as many - operators as you like. The difference is that + operators don't change the value where - operators do.
In C-based languages, assignments actually return a value where they don't in VB. In C#, you can do this:
i += 1
and it will get the value of i, add 1 to it, assign the result back to i and then return that result, so you can use that expression where a value is expected. In VB, it does all the same things up to the assignment but it does not return a value, so you cannot use that expression where a value is expected.
In C-based languages, where you place the ++ operator makes a difference. The expression:
++i
increments i and returns the final value, whereas this expression:
i++
increments i and returns the original value. That's why some argue that the C++ language should actually be named ++C.
I am new to bison, and have the misfortune of needing to write a parser for a language that may have what would otherwise be an operator within a variable name. For example, depending on context, the expression
FOO = BAR-BAZ
could be interpreted as either:
the variable "FOO" being assigned the value of the variable "BAR" minus the value of the variable "BAZ", OR
the variable "FOO" being assigned the value of the variable "BAR-BAZ"
Fortunately the language requires variable declarations ahead of time, so I can determine whether a given string is a valid variable via a function I've implemented:
bool isVariable(char* name);
that will return true if the given string is a valid variable name, and false otherwise.
How do I tell bison to attempt the second scenario above first, and only if (through use of isVariable()) that path fails, go back and try it as the first scenario above? I've read that you can have bison try multiple parsing paths and cull invalid ones when it encounters a YYERROR, so I've tried a set of rules similar to:
variable:
STRING { if(!isVariable($1)) YYERROR; }
;
expression:
expression '-' expression
| variable
;
but when given "BAR-BAZ" the parser tries it as a single variable and just stops completely when it hits the YYERROR instead of exploring the "BAR" - "BAZ" path as I expect. What am I doing wrong?
Edit:
I'm beginning to think that my flex rule for STRING might be the culprit:
((A-Z0-9][-A-Z0-9_///.]+)|([A-Z])) {yylval.sval = strdup(yytext); return STRING;}
In this case, if '-' appears in the middle of alphanumeric characters, the whole lot is treated as 1 STRING, without the possibility for subdivision by the parser (and therefore only one path explored). I suppose I could manually parse the STRING in the parser action, but it seems like there should be a better way. Perhaps flex could give back alternate token streams (one for the "BAR-BAZ" case and another for the "BAR"-"BAZ" case) that are diverted to different parser stacks for exploration? Is something like that possible?
It's not impossible to solve this problem within a bison-generated parser, but it's not easy, and the amount of hackery required might detract from the readability and verifiability of the grammar.
To be clear, GLR parsers are not fallback parsers. The GLR algorithm explores all possible parses in parallel, and rejects invalid ones as it goes. (The bison implementation requires that the parse converge to a single possible parse; the original GLR algorithm produces forest of parse trees.) Also, the GLR algorithm does not contemplate multiple lexical analyses.
If you want to solve this problem in the context of the parser, you'll probably need to introduce special handling for whitespace, or at least for - which are not surrounded by whitespace. Otherwise, you will not be able to distinguish between a - b (presumably always subtraction) and a-b (which might be the variable a-b if that variable were defined). Leaving aside that issue, you would be looking for something like this (but this won't work, as explained below):
expr : term
| expr '-' term
term : factor
| term '*' factor
factor: var
| '(' expr ')'
var : ident { if (!isVariable($1)) { /* reject this production */ } }
ident : WORD
| ident '-' WORD { $$ = concatenate($1, "-", $3); }
This won't work because the action associated with var : ident is not executed until after the parse has been disambiguated. So if the production is rejected, the parse fails, because the parser has already determined that the production is necessary. (Until the parser makes that determination, actions are deferred.)
Bison allows GLR grammars to use semantic predicates, which are executed immediately instead of being deferred. But that doesn't help, because semantic predicates cannot make use of computed semantic values (since the semantic value computations are still deferred when the semantic predicate is evaluated). You might think you could get around this by making the computation of the concatenated identifier (in the second ident production) a semantic predicate, but then you run into another limitation: semantic predicates do not themselves have semantic values.
Probably there is a hack which will get around this problem, but that might leave you with a different problem. Suppose that a, c, a-b and b-c are defined variables. Then, what is the meaning of a-b-c? Is it (a-b) - c or a - (b-c) or an error?
If you expect it to be an error, then there is no problem since the GLR parser will find both possible parses and bison-generated GLR parsers signal a syntax error if the parse is ambiguous. But then the question becomes: is a-b-c only an error if it is ambiguous? Or is it an error because you cannot use a subtraction operator without surround whitespace if its arguments are hyphenated variables? (So that a-b-c can only be resolved to (a - b) - c or to (a-b-c), regardless of whether a-b and b-c exist?) To enforce the latter requirement, you'll need yet more complication.
If, on the other hand, your language is expected to model a "fallback" approach, then the result should be (a-b) - c. But making that selection is not a simple merge procedure between two expr reductions, because of the possibility of a higher precedence * operator: d * a-b-c either resolves to (d * a-b) - c or (d * a) - b-c; in those two cases, the parse trees are radically different.
An alternative solution is to put the disambiguation of hyphenated variables into the scanner, instead of the parser. This leads to a much simpler and somewhat clearer definition, but it leads to a different problem: how do you tell the scanner when you don't want the semantic disambiguation to happen? For example, you don't want the scanner to insist on breaking up a variable name into segments when you the name occurs in a declaration.
Even though the semantic tie-in with the scanner is a bit ugly, I'd go with that approach in this case. A rough outline of a solution is as follows:
First, the grammar. Here I've added a simple declaration syntax, which may or may not have any resemblance to the one in your grammar. See notes below.
expr : term
| expr '-' term
term : factor
| term '*' factor
factor: VARIABLE
| '(' expr ')'
decl : { splitVariables(false); } "set" VARIABLE
{ splitVariables(true); } '=' expr ';'
{ addVariable($2); /* ... */ }
(See below for the semantics of splitVariables.)
Now, the lexer. Again, it's important to know what the intended result for a-b-c is; I'll outline two possible strategies. First, the fallback strategy, which can be implemented in flex:
int candidate_len = 0;
[[:alpha:]][[:alnum:]]*/"-"[[:alpha:]] { yymore();
candidate_len = yyleng;
BEGIN(HYPHENATED);
}
[[:alpha:]][[:alnum:]]* { yylval.id = strdup(yytext);
return WORD;
}
<HYPHENATED>"-"[[:alpha:]][[:alnum:]]*/"-"[[:alpha:]] {
yymore();
if (isVariable(yytext))
candidate_len = yyleng;
}
<HYPHENATED>"-"[[:alpha:]][[:alnum:]]* { if (!isVariable(yytext))
yyless(candidate_len);
yylval.id = strdup(yytext);
BEGIN(INITIAL);
return WORD;
}
That uses yymore and yyless to find the longest prefix sequence of hyphenated words which is a valid variable. (If there is no such prefix, it chooses the first word. An alternative would be to select the entire sequence if there is no such prefix.)
A similar alternative, which only allows the complete hyphenated sequence (in the case where that is a valid variable) or individual words. Again, we use yyless and yymore, but this time we don't bother checking intermediate prefixes and we use a second start condition for the case where we know we're not going to combine words:
int candidate_len = 0;
[[:alpha:]][[:alnum:]]*/"-"[[:alpha:]] { yymore();
candidate_len = yyleng;
BEGIN(HYPHENATED);
}
[[:alpha:]][[:alnum:]]* { yylval.id = strdup(yytext);
return WORD;
}
<HYPHENATED>("-"[[:alpha:]][[:alnum:]]*)*[[:alpha:]][[:alnum:]]* {
if (isVariable(yytext)) {
yylval.id = strdup(yytext);
BEGIN(INITIAL);
return WORD;
} else {
yyless(candidate_len);
yylval.id = strdup(yytext);
BEGIN(NO_COMBINE);
return WORD;
}
}
<NO_COMBINE>[[:alpha:]][[:alnum:]]* { yylval.id = strdup(yytext);
return WORD;
}
<NO_COMBINE>"-" { return '-'; }
<NO_COMBINE>.|\n { yyless(0); /* rescan */
BEGIN(INITIAL);
}
Both of the above solutions use isVariable to decide whether or not a hyphenated sequence is a valid variable. As mentioned earlier, there must be a way to turn off the check, for example in the case of a declaration. To accomplish this, we need to implement splitVariables(bool). The implementation is straightforward; it simply needs to set a flag visible to isVariable. If the flag is set to true, then isVariable always returns true without actually checking for the existence of the variable in the symbol table.
All of that assumes that the symbol table and the splitVariables flag are shared between the parser and the scanner. A naïve solution would make both of these variables globals; a cleaner solution would be to use a pure parser and lexer, and pass the symbol table structure (including the flag) from the main program into the parser, and from there (using %lex-param) into the lexer.
Is there such a thing as a Limit operator that lets you control the maximum or minium value of a variable.
if variable > value then variable = value
My question is not language specific, but answers in different languages are appreciated (esp. Delhpi).
I know operators differ from language to language, but mostly in syntax.
Would an operator like this be usefull enough?
Some languages have "min" operator that can be used for this: variable = min(variable, limit)
Basically, an operator is nothing else than a function.
Unary operators like ! (not) can be mapped with the function
Boolean not(Boolean)
Binary operators like + (plus) can be mapped with the function
Integer plus(Integer, Integer)
...
So, you can define any missing "operator" on your own as a function. Many languages don't allow to define operators on your own. In Groovy you can overload existing operators:
http://groovy.codehaus.org/Operator+Overloading