hello = ^{ "Hello " + name }
does. I (and my grandmother as well, for that matter) would understand that a lot better if it was a lot more explicit, like function hello(name) do
"Hello " + name hello = ^{ "Hello " + name }
does. I (and my grandmother as well, for that matter) would understand that a lot better if it was a lot more explicit, like function hello(name) do
"Hello " + nameWhether to write:
hello = lambda (name) { "Hello " + name }
hello = ^ (name) { "Hello " + name }
hello = function (name) { "Hello " + name }
is just a color of the bike shed decision.
You might say that significant whitespace (i.e. the indentation level signifies structure) is a more natural way, but when you think about it there's no where else in these peoples lives where indentation of text determines it's function or effect. When you e.g. in Word indent text it's a purely visual effect (which might imply or give greater meaning to structure, but not define it). Thus, significant whitespace is not as natural as parenthesis and -- it turns out -- curly braces.
Now, I only did qualitative research and have yet to see a large uptake in usage. I personally use Move for 95% of everything I write nowadays and I have colleagues and friends who are also writing things in Move, so I guess time will tell if this is actually a more "natural" programming language than, say, JavaScript.
I recently wrote this update on the Move language. A sort of retrospect: http://rsms.me/2011/07/30/an-update-on-move.html
If they wanted "smaller" lambdas, why not use e.g. C#'s syntax? Or Scala's?
Also, implicit scoping => yet an other broken language. Not worth looking at.
What other solution do you propose? Demanding all variables are declared? That's a very good idea, but it goes against the spirit of javascript and other dynamic languages.
After extensive experience with it in Python and Ruby, I don't. It's just too prone to typos and broken scoping to be worth it.
> What other solution do you propose? Demanding all variables are declared?
yes.
> That's a very good idea, but it goes against the spirit of javascript and other dynamic languages.
No it does not.
* Javascript has explicit scoping, it's mandatory in strict mode (ES5) and extensions add even more flexible scoping methods (e.g. `let` in Mozilla's JS 1.7[0])
* Likewise with Perl under `use strict`
* Or even in VB and VBScript using Option Explicit
* Smalltalk mandates declaring local variables
* Scheme (and more generally lisps) make extensive use of `let`-type blocks
Dynamic typing and implicit scoping are entirely orthogonal, and I truly find no value whatsoever in implicit scoping: it's a hindrance in every situation, and it helps in none.
[0] https://developer.mozilla.org/en/New_in_javascript_1.7#Block...
> It's just too prone to typos and broken scoping to be worth it.
Predeclared variables are just as prone to typos, which will also break your code -- and just as prone to broken scoping. By accidentally shadowing an external variable you make it unreachable for the remainder of the current function, and all nested functions within.
Clearly, declaring the type of a variable is not necessary in a dynamic language, so the only purpose of a variable declaration is to manually mark it's scope, shadowing any potential name conflict.
There are no situations where shadowing a variable is desirable. It's always best to be able to reach any variable that exists in the current lexical scope, should you find the need.
The only ambiguous situation in which you'd want to use a "var" on purpose is to explicitly shadow an external variable of the same name -- if you accept that shadowing is undesirable, and choosing a more descriptive name for the inner variable is preferable, then QED.
Dynamic languages should not have variable declarations.
Not so: declaring variable name & scope ensures immunity to the "I wanted to change this variable, but I'm creating a new one instead", and this can be checked statically even in dynamically typed languages.
> There are no situations where shadowing a variable is desirable.
While I do not agree with this assertion, I can see where you come from and explicit scoping is still superior to implicit for this: if there are no situation where shadowing is desirable, you can make the language statically forbid shadowing. There, done.
> It's always best to be able to reach any variable that exists in the current lexical scope, should you find the need.
It is not, however, desirable to reach and unknowingly alter an existing variable in an ancestral lexical scope when you did not mean to and just happened to pick an existing name in a callback 2-levels down the stack. The result of this is silent corruption of program state, and it is a risk in any implicitly-declared scoping system with mutable bindings.
> The only ambiguous situation in which you'd want to use a "var" on purpose is to explicitly shadow an external variable of the same name -- if you accept that shadowing is undesirable, and choosing a more descriptive name for the inner variable is preferable, then QED.
Then QED nothing, since as I pointed out it is perfectly possible to make variable shadowing statically illegal, ensuring that no variable is hidden and no variable is silently reused or replaced either.
> Dynamic languages should not have variable declarations.
Nope.
Furthermore, explicit scoping significantly increases readability and lowers cognitive burden: readers don't have to wonder whether a given assignment is local to the current lexical scope, it's spelled out for them. And if it's a bare assignment (not a new variable), explicit scoping makes it easier to find out where the variable is first used. Not to mention it allows the language to protect against in-scope reuse (in cases of debatable-quality imperative code with scopes more than a screenful long), as the second declaration may (and generally will) be statically marked as the redeclaration of an existing variable, and will be refused by the language's runtime.
And all of that for the cost, in most languages, of 3 characters. Almost nothing. All the issues you mentioned (since you didn't mention typing) are not issues of explicit scoping but with specific implementations thereof.
You declared a variable once and use it n times. If you accidentally shadow a variable, via typo, then you only have one place to check for the typo. The compiler/interpreter will complain if you don't happen to also consistently made that typo everywhere you use the variable.
In language with implicit declaration, everywhere you use the variable is as likely to have typo that the compiler/interpreter cannot check for you.
1 place to check vs. n places, is a no-brainer which one is more error prone.
> By accidentally shadowing an external variable ...
In language with explicit declaration you have to accidentally declare same name AND use it with that accidental name. If both doesn't happen, the interpreter will complain.
In language with implicit declaration, one accidental typo is all it takes to accidentally shadow a variable.
You have just made a case against implicit declaration.
> There are no situations where shadowing a variable is desirable. [...] if you accept that shadowing is undesirable, and choosing a more descriptive name for the inner variable is preferable
So, to name a local variable "list", you have to look up on every outer variables involved to make sure nowhere else also use the name "list".
And let's give up on naming an outer variable name "list" because, who knows where some inner function might decide to use such name for local variable.
> choosing a "more descriptive name" for the inner variable
More like "more redundant name". Implementing "date_diff" function? Forget naming different of it "delta", let's name it "date_diff_delta", or else it might conflict with some outer variable name.
Congratulation, you have successfully remove concept of namespace from your language.
> if you accept that shadowing is undesirable
Then you should consider other job than programming.
int (^aBlock)(int) = ^(int a) {
return a;
}; hello = \name -> putStrLn ("Hello, " + name)
That said, Haskell doesn't end up needing no-arg functions the way JavaScript does, but I think "\-> { }" wouldn't be too bad. At the least it does a slightly better job of resembling a lambda than the caret.