The "return void values from functions" issue reminded me of an idea I had several years ago for shorter "functional programming" style function definitions. The idea is that a function that just returns an expression can be written without the block and return statement:
int add(int a, int b) = a + b; string `id() = "foo"; void delay(int ms) = sleep(ms*0.001);
(The last example is where the "returning void" thing becomes relevant. :)
It turns out that this can be implemented by adding a single line to language.yacc, so I pushed an implementation to the branch marcus/short_func.
Opinions on adding this to 8.1?
Does it make any code more readable or easier to write? Or is it just for the heck of it?
It makes the code a bit more concise, which improves both writeability and readability. But the difference is not huge, which is why I'm soliciting opinions. :-)
Javascript has a syntax for this, though more as more streamlined way of writing lambdas. It would look kind of like this
add = (a,b) => a+b; id = () => "foo"; // No `id in js I think... delay = (ms) => sleep_if_it_existed(ms*0.001);
I find the syntax to be really difficult to be comfortable with, because it makes it hard at a glance to make out what is immediately executed expressions and what are executed at a later stage.
Without having made up my mind in any direction, I think this is my current state:
1. Asynchronous programming requires more language support than we provide today. One part of the equation is to improve promises and async-specific keywords and helper objects. One part is to improve functional programming constructs, which asynchronous tend to generate a lot of. This is a reason for doing this change.
2. The more powerful tools and abstractions we introduce, the harder it is to read the code. Example: I love how clean the code looks after a good application of implicit lambda, but it is very hard to figure out how the code works without knowing about it beforehand. This is a reason against doing this change.
3. I think we need to be very careful with new langauge features that are different from other syntactically similar langauges. Better is good, but different is bad.
I'm not fully convinced of the syntax proposed by Marcus. If the expression contains an assignment it leads to multiple "=" signs that look weird.
In my testing now I see that Pike also supports inline declaration of a variable in a "return" statement. Not sure if this is by accident, but it can create further confusion as seen below.
Before:
int x; int foo() { return x = 17; } // modify global x int bar() { return int x = 17; } // should this be legal btw?
After:
int x; int foo() = x = 17; // looks bad int bar() = int x = 17; // looks worse, and not global x
The use of "=>" at least gives a cleaner separation of the two parts of a definition.
Well, returning an assigment wouldn't be very functional style in the first place. :-) But the "=" could of course be replaced with something else. The only things it could _not_ be is "{" or ";", basically. As for "=>", that is currently not a token, and introducing a new token is a slightly bigger change I think. "<=" is a token, and kind of makes sense since the value is returned back to the caller...
In that case, I think ":" would be better. Visually and in line with some functional languages, "->" could also be an option, except that it maybe feels a bit too different from what that tokens means in other contexts in Pike.
pike-devel@lists.lysator.liu.se