I think the idea is good, but I think it would be bad for the language overall.

-1

As a plus, it makes code easier to write, sometimes; or at least it seems so. 
On the other hand, I think it makes code harder to comprehend. A `with` 
statement introduces a new scope in which it is not obvious what exactly 
happens. For example:

with(someObject) {
    foo()
}

what does it do? The mere fact that I wrote `with(someObject)` suggests that 
`someObject.foo()` is what should happen. But it could also mean `self.foo()` 
or just the global function `foo()`.

Usually, you can see from the lexical surrounding of a call, what is happening. 
`foo()` means either `self.foo()`, or it means `foo()`. It's okay that I, as 
the class author know if my class has a `foo()` method or not. But do I have to 
know the API of someObject completely, including any future changes to its API?

For example: Suppose I have a class Foo, which has a method foo(). A remote 
co-worker wrote class Bar, which has a method bar(). Because I need bar a lot 
recently, I decided to use the with() form:

with(someBarObject) {
   ...
   foo()
   ...
   bar()
   ...
   bar()
   ...
   foo()
}

All is fine, it's clear that foo() calls my method and bar() calls that method 
on the someBarObject object. Then, suddenly, my co-worker had a great idea! He 
also implements foo() - it cannot break any existing code doing so, because 
existing code will not call foo(), because up until now class Bar did not 
implement foo(), after all...

Suddenly, my Foo class breaks, because my co-worker implemented foo() in his 
own class :-o

Such a thing really shouldn't happen. I am arguing that `with` is an inherently 
unsafe language feature! I also think it doesn't make the code actually easier 
to read. It may be an advantage if you have some 
reallyReallyLongAndFunnyVariableNames_withUnderscores_andSpecialTypeAnnotations,
 but even then I think it isn't worth it. I prefer easy-to-read over 
easy-to-write.

I like it when I can know what some code does, just by looking at it locally. 
These are syntactic guarantees that I can depend on. E.g. when I read something 
like

    x.bar()
    foo()

I know that there is an x variable somewhere (either in the current instance, 
or globally, or a local variable; a global variable is unlikely, because no one 
should dare to call a local variable just x.)
I know that the bar() method is called on that variable x, so x implements the 
bar() method. Either itself, or through an extension.
foo() is either a global method, or an instance method, or a static method.
All of these questions can be answered if I just know the class that I am 
currently implementing. If I know that my class didn't implement foo(), then 
foo() must be global. If x is a local var, an iVar or a static var, I can tell 
just by looking at the surrounding code. If it isn't => it must be global.
This (let me call it) "lexical decidability" is reduced by a `with`-operator, 
and this is the primary reason why I don't like it. For exactly this reason, I 
use a convention when writing Objective C code, that iVars should always be 
prefixed by an underscore, static and global vars always start with an 
uppercase letter, and all local vars and parameters start with a lowercase 
letter.

***

Even if we use .bar() instead of just bar() when calling from within a `with` 
block, I still don't like it. How many keystrokes are we sparing? If the 
variable has two letters, e.g. it's named `br`, we have `with(br){` (9 
characters, 1 newline) and `}` (1 character, 1 newline) compared to 2 
keystrokes for each time you may omit `br`. If you count the newlines as 
characters, you have to use the variable br 7 times in order for the `with` 
statement to pay off.

***

Using { $0.bar() } is interesting too. But why?? Just give the variable a short 
name, call it x0, for example, and you are saving even more keystrokes.

***

IMHO, saving sourecode-bits is not everything; readable code is everything. 
Therefore, a -1 from me.

-Michael

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to