4 ms·
I am entirely in agreement contingent upon there being some language construct which makes it possible to explicitly limit which variables from one block can be
by tome 7y ago
I am entirely in agreement contingent upon there being some language construct which makes it possible to explicitly limit which variables from one block can be seen in subsequent blocks. For example
DoAll() {
// A
a1 = ...
a2 = ...
a3 = ...
withOnly a1, a3:
// B
b1 = f(a1)
b2 = g(a3)
withOnly b2:
// C
c1 = h(b2)
}
Since this doesn't exist in any language, as far as I know, I guess I'll stick to using functions for now.
- kchamplewski 7y agoC-style languages tend to have squiggly brackets which can limit scope somewhat, but not as totally as you describe. For example: doThing(){ x = 7; //x visible in whole function { y = x*2; //y only visible in this block. } // x still visible, y no longer visible } Explicitly removing things from scope doesn't seem to be a feature though.
- twic 7y agoThe application i am working on right now has a 766-line setup method written like this. Each block corresponds to the setup of one component. If there is something from that block that needs to be reused (typically, the channels that the component published data to), it is declared immediately above the block. Many small bits of logic are broken out into their own methods (checking if today is a public holiday, configuring the HTTP server, configuring the KV store client, etc), but the setup of the domain logic components is all in one method. There's no way to split the setup of the components into methods without either introducing a comparable volume of boilerplate, or having to write some kind of framework to make it easier. Neither would be a win. A caveat: this codebase uses a language which doesn't have out parameters or multiple-value returns. If it could use those, the boilerplate involved in breaking up the setup method would be considerably smaller. But still probably not worth it.
- tremon 7y agoIt does exist, through closures. The syntax in most languages doesn't improve the readability of the code though: DoAll() { // A a1 = ... a2 = ... a3 = ... // B b2 = lambda(x,y) { b1 = f(x) b2 = g(y) }(a1,a3); // C lambda(x) { c1 = h(x) }(b2); } I've added explicit intermediates to better visualize where the scope binding happens, but most languages allow the compiler to bind these variables implicitly whenever an anonymous function references variables from outer scope. That helps with readability, but not with scoping.
- mike_hock 7y agoBut that doubly defeats the purpose. 1. If you have good reasons to restrict variable access in subsections of your long procedure, then it DOES make sense to factor them out as separate functions. 2. Closures automatically close over variables from the surrounding scope (duh), so they don't protect you from accidentally using a variable in a section that you're not supposed to use it in.
- davvolun 7y agoThe lambda approach avoids "I can't think of what I should call this, I'll call it `foo` for now" problem... Which isn't a problem we should be avoiding. Naming things in a way that other coders will understand is an important skill, and can be difficult.
- mike_hock 7y agoHow does it avoid that problem? The lambda doesn't help me understand what that part actually does any more than calling the function "foo_helper" or "foo_partN" or something like that would do.
- davvolun 7y ago> Which isn't a problem we should be avoiding I believe we're actually arguing the same thing. Anonymous functions aren't the end of the world, but self-documenting code is better. In the JS/JQuery world, breaking away from anonymous functions would represent such a fundamental shift in practice, I'm not going to do it on my own, but in Angular, I stay away from anonymous functions.