Arc Forumnew | comments | leaders | submitlogin
3 points by rocketnia 2102 days ago | link | parent

It looks like the particular solution you'd like is for `=` to act as it does in Python, but I think Arc's behavior is preferable to Python's.

For a variable to "default" to "global scope" is basically the definition of how lexical scope works. To find a variable's binding occurrence, you look outward until you find it. Once you go far enough out, you get to the language definition itself, which ultimately must provide some "global" catchall case.

Python makes lexical scope much more complex to describe: Every variable is declared at a module (or REPL), class, or function boundary. To find the boundary where a variable is declared, first you look for the nearest boundary. If you've found a module boundary or a function boundary where the variable is in the parameter list, you're done. Otherwise, you search that boundary for any `=`, `global`, or `nonlocal` declarations of that variable. If you find `global`, you skip to the nearest module boundary, and you're done. Otherwise, if you find one or more `=` declarations and don't find `nonlocal`, you're done. Otherwise, you repeat this process at the next nearest boundary.

I do sympathize with a couple of the pain points you're talking about:

1. If a variable name is written with a typo, Arc's `=` will silently assign to a misspelled global binding. I think it'd be more ideal to alert the programmer to an error like C does.

2. To declare a local variable, an Arc programmer must use things like `let` and `with`, which add layers of parentheses and indentation. In C (ever since C99) and Python, local variable declarations can be performed in the middle of a block, and they don't affect the indentation of the following code.

For point 1, most of the time I like to program without using `=` at all.

For point 2, I think Lisp's prefix notation and lambda notation facilitate a style that uses more deeply nested expressions than you might be used to. When expressions can be more deeply nested, they don't have to be broken apart across quite as many local variables, so writing `let` and `with` forms here and there doesn't pose a serious problem most of the time. That said, I use what I call "weak opening parens" and a certain indentation style to do away with this extra nesting anyway (https://github.com/lathe/parendown-for-racket).