Hacker News new | past | comments | ask | show | jobs | submit login
Move.js (movelang.org)
87 points by superted on Aug 9, 2011 | hide | past | favorite | 31 comments



The project's GitHub repo[1] does a much better effort of selling it:

When compared to JavaScript, Move has the following key features:

- Simpler. E.g. there's only one way to declare functions, no need for var declarations, only a single type of equality operators and no need for terminating statements with semicolons.

- Less boiler-plate code needed. Move introduces a few carefully selected features like the "import" and "export" keywords, and @-shorthand for this access.

- Move runs in any >=ES3 JavaScript runtime and thus can be used as a universal programming language for everything from running in web browsers to powering complex offline systems.

Also, interestingly, it's from the guy behind Kod and Spotify's design.

[1] https://github.com/rsms/move


For a "my first programming language", it's a bit too "programming language". It took me a few seconds to understand what

    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


Actually, I spend a week doing hands-on interviews with actual people whom had no prior programming experience. At first, I thought details like curly brackets, parenthesis and so on would put them off, but not a single person had a problem with that, to my surprise.

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 you squint a little the ^ looks like a lambda with the top missing. The syntax thus makes sense to me.

Whether 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.


Not really, "^" is too dense and very different from natural language (if the target is beginners, otherwise you're right).


I agree, ^{} is fairly inadequate to delimit a function.


Likewise. Why the hell did they get a syntax shoehorned into C for a language which does not have such constraints?

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.


May I ask, why is implicit scoping bad? I think it is very good for a dynamically typed language, where variables do not need to be declared beforehand.

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.


> May I ask, why is implicit scoping bad? I think it is very good for a dynamically typed language, where variables do not need to be declared beforehand.

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...


To give the counter-argument some weight: I disagree, wholeheartedly. Explicit variable declaration is a throwback inherited from statically-typed language, where a variable's type must be declared before use, and has no place in a dynamic language.

> 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.


> 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.

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.


> Predeclared variables are just as prone to typos, which will also break your code

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.


I think that the author took inspiration from Objective C blocks:

  int (^aBlock)(int) = ^(int a) {
    return a;
  };


agree, many nonenglishmen will probably have a problem to even type the ^ symbol on their keyboars..


I still think I like haskell's approach to this problem:

  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.


Absolutely. What a terrible syntax.


For a language that's targeted at non-programmers I don't see how Move offers any benefits over Coffeescript, or even Javascript itself particularly.

Programming should change the way you think. The language is an artifact that you program through, but that's not the critical problem in conceiving of and executing good software design.

A cursory examination of the Move site does not make it look more attractive than other Javascript based languages, and the explanations it offers i don't think would make it more accessible to non-programmers either.

What gives? /me is confused.


For Rasmus' opinions on Move vs CoffeeScript, see: http://www.quora.com/Rasmus-Andersson-What-are-the-pertinent...


I should add that i'm not using a fair cognitive framing.

It doesn't have to be Coffeescript vs Move or Move vs anything. I don't think that rsms achieves what his site seems to set out to do, although i agree that a common ES5 behavioral platform is a good thing.

His opinion of CoffeeScript is interesting, and provides some insight into his motivation, i guess, but i think i may have introduced a red-herring into the conversation.


A little more details from the author of Move.js: http://rsms.me/2011/07/30/an-update-on-move.html


The more i read, the less i like :(

The prototypal inheritance example in that post does not read in an intuitive manner, and certainly don't improve the clarity of meaning for prototypal inheritance (especially now that it's using the word "class").

The only compelling thing i can find in here so far is that it's trying to provide common functionality from ES5. But again, i don't see what that has to do with building a language that is easy for non-programmers to grok, making the Javascript semantic model more accessible, or even making JS coding more readable.


So the differences between this and Javascript that I can see are:

    * ^ replacing function
    * default values for arguments, ^(x: 4){...}
    * print instead of console.log
    * array slicing x[1:3], x[:-2]
    * embedded HTML, div = <div/>
Interesting, but this isn't convincing enough for me to use it.

Edit: like beaumartinez says, the Github page explains the differences much better than the site: https://github.com/rsms/move


Also implicit variable scoping. And does not (as far as I can see) facilitate properties creation, nor does it implement tuple unpacking/multiple return values, and positional v keyword arguments use completely different syntaxes (not sure if you can even mix them).

Overall, seems very half-assed, a few cosmetic changes (half of them making the language worse instead of better) and that's about it.


This seems to me to take up a similar space in javascript as velocity and freemarker do for Java. They attempt to make programming simpler for designers to work with and instead end up with a language that is too complicated for a designer and a completely new syntax for an engineer. Now, it takes more time for anyone to work with it.

For example, no need for var declarations. Well, wait a minute, how do I as an engineer scope a variable then? In javascript, scope is determined by functions when using a var and is global otherwise. Are all variables global? Or are they just in a namespace? Or are they all scoped as if they had var in front? Things like this will trip me up all the time and I will always have to refer to documentation.

For designers, mostly they don't want to work with functions and variables anyway, how big of a benefit is it that they don't need a var and there is only one way to declare a function? Learning this language seems like it would take the same amount of overhead as learning identical features in javascript. Why not just learn a subset of javascript instead?


This is a nice idea but the execution is convoluted.

I think writing LOGO in the browser with something similar would be cool.

http://en.wikipedia.org/wiki/Logo_(programming_language)

    FORWARD 100
    LEFT 90
    FORWARD 100
    LEFT 90
    ...
is a better introduction to programming...


Your wish has been fulfilled! http://www.calormen.com/logo/


one would expect that such language would have fixed js objects, e.g. arrays not allowing wild things like

  a = []; a[10] = undefined; a["x"] = "foo"


print foo.makeHello capitalize name

The right associativity of function application is a very peculiar feature and it turns my Haskell brain upside down.


It also makes my non-haskell brain as well, for what it's worth.

edit: wait, its functions are not curried, so I'm not sure it's right-associative, it just looks that way if you've read haskell code in the past: positional arguments are still tuples (comma-separated)

If this code was haskell and you translated it to Move it would look like this: `print foo.makeHello, capitalize, name`


I just loved how it clearly told me its for beginners. That means I can skip this one! Yay!


Like a Ruby




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: