Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Python doesn't have implicit declaration. The first occurrence of the assignment syntax declares the variable and binds it to a value.

Proof that Python doesn't have implicit declaration:

  >>> foo
  Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
  NameError: name 'foo' is not defined
Pyhon's design sin is that it fails to distinguish the binding of a variable from assignment. The programmer cannot locally (i.e. just in that statement alone) express "I expect this statement to be freshly creating a variable, introducing it into the scope, with value 42" and "I expect to be assigning value 42 to a variable which already exists in the scope (or else this should be diagnosed)".

An example of a language actually without declaration is Awk. This helps one-liners be very terse, but hinders large programs.

Proof that awk has implicit declaration in contrast to Python:

  $ awk 'BEGIN { print foo }'

  $
No errors. The shell has implicit declaration:

  $ echo $foo
You turn it off in serious scripts with "set -u" to have it diagnosed.


Likewise is the idea that if a variable isn't defined, it can be treated as an unknown mathematical variable of sorts

So if x is unbound, x + x evaluates to 2x

And if x = 2, x + x evaluates to 4

But this means that it's hard to catch typos!

AFAIK Mathematica works like this.


If Mathematica couldn't simplify formulas over variables that are not instantiated, what good would it be? That's an important job of a computer algebra system.


Yes being a CAS and a general purpose language is at odds. I guess there's two paths

a) use sigils to signal that some variable should be treated as an abstract values for CAS purposes. like, :x + :x rather than x + x (or.. use sigils to signal that a variable is "normal", like $x is a normal variable and x + x is CAS stuff)

b) declare CAS variables as such before using them. like with a "var" keyword or something. optionally, declare normal variables, but with a different keyword

Note that formal math always look like "b)" (we declare our variables before using them), it's informal math that looks what Mathematica is doing


> Python doesn't have implicit declaration. The first occurrence of the assignment syntax declares the variable and binds it to a value.

That's exactly what he means by "implicit declaration" though - he even calls out Python as an example.

Python does have implicit declaration, it is just slightly more limited than languages like Bash and CMake - it only implicitly declares variables when you write to them, not when you read them.

Anyway, regardless of the semantics I think we all agree that all forms of implicit variable declaration are a bad idea.


Betz should fix his terminology to align with the industry.

There is nothing implicit about x = 42 in Python. You wrote it explicitly.

The language is not pretending that you invisibly defined x somewhere at the top and are now assigning it.

The most familiar "implicit declaration" to everyone is the feature in traditional C (that any good C compiler warns about and was banished in C++ early). Like that you can call a function without declaring it:

  puts("Hello"); /* no <stdio.h> included */
The compiler looks at the argument types and deduces a declaration. The return type is assumed to be int, and since the "Hello" expression decays to char * type, the implicit declaration is int puts(char *).

Python actually doesn't have declarations at all (except when we consider the new typing features).

When we introduce something into a scope without giving any attributes about it like type, that's a definition. A declaration is something which makes facts known about an identifier: like whether it is a constant, does it have a type, and such. It doesn't necessarily make it exist.

In Lisp declarations can be added about an existing identifier:

   (let ((x 3)) ;; definition of x
     (declare (type (integer x))) ;; declaration about x
     ...)
In languages focused on static type, definitions declare. E.g. in C, all definitions (other than of macros) are declarations; not all declarations are definitions.

In Python, a variable must be visibly defined before it is used, quite clearly; it doesn't have implicit definition. Untyped Python has no declarations.


> There is nothing implicit about x = 42 in Python. You wrote it explicitly.

You wrote the assignment explicitly. You did not write any declaration that "a variable x should already exist" anywhere did you?

> Betz should fix his terminology to align with the industry.

His terminology is aligned with the industry. Google it. Here are the top two results for me:

* https://www.quora.com/What-does-the-explicit-and-implicit-de... * https://stackoverflow.com/questions/56999347/variable-declar...

> Like that you can call a function without declaring it:

That's exactly the same as your Python example!! "There's nothing implicit about `puts("Hello");`. You wrote it explicitly."

> When we introduce something into a scope without giving any attributes about it like type, that's a definition. A declaration is something which makes facts known about an identifier: like whether it is a constant, does it have a type, and such. It doesn't necessarily make it exist.

No. A declaration can only declare that a variable exists. Consider this in Javascript:

    let foo;
Not "having" declarations and declarations being implicit are exactly the same thing. You're getting tripped up over your language.


> A declaration can only declare that a variable exists.

Yes; that's the only correct thing in your comment.

A declaration can declare that a variable exists, and nothing more, which is useful in some language that has a strict rule that variables must have been indicated as existing before they can be used.

If a declaration causes the variable to exist, then it's a definition.

However, about that specific example, "let foo;" in Javascript is actually a definition. It causes foo to exist in the scope where it appears, with a value of undefined.


> Pyhon's design sin is that it fails to distinguish the binding of a variable from assignment. The programmer cannot locally (i.e. just in that statement alone) express "I expect this statement to be freshly creating a variable, introducing it into the scope, with value 42" and "I expect to be assigning value 42 to a variable which already exists in the scope (or else this should be diagnosed)".

I'm not entirely sure this is a bad thing? I'm learning Go right now, and I'm encountering plenty of code like:

    err := DoFoo()
    if err != nil ....

    err = DoBar()
    if err != nil ....
The problem with that is that if you remove the DoFoo line you have to change the DoBar line, even though nothing's really changed there. An (albeit small) waste of time, an extra thing to think about which has nothing to do with the problem you're solving, more lines to review in the PR, and more chance of merge conflicts later.


You could bind the variable each time, if that is allowed:

  err := DoFoo();
  if err != nil ...


  err := DoBar()
  if err != nil ...
DoFoo and DoBar are different functions; their error return might not even be the same type.

If mixed declarations and statements are not supported:

  {
    err := DoFoo();
    if err != nil ...
  }


  {
    err := DoBar()
    if err != nil ...
  }
this is what I do in C to reduce the scope of variables, and it has the benefit over the former example in that we delimit where the scope begins and ends. We know that after the closing brace, nothing can be referencing that err variable. (I'm not a fan of mixed decls and statements).

Modern languages should support binding a variable in if:

  if (err := DoFoo()) {
    // err scoped here
  }
My first example would be "bad" according to David Betz because it perpetrates shadowing.


You can avoid this by using :

  if err := DoFoo(); err != nil { ...
The 'err' variable will be local to the 'if' so you can write also :

  if err := DoBar(); err != nil { ...
It is also nice to write it in one line :-)


You've just hit Go's design flaw: error handling.




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

Search: