6 ms·
Since you’re updating it anyway, the very first example says "D has @property functions, which are methods that you call with what looks like field access, so i
by david2ndaccount 3y ago
Since you’re updating it anyway, the very first example says "D has @property functions, which are methods that you call with what looks like field access, so in the above example, c.d might call a function.”
It is true that `c.d` might call a function, but it’s not because of @property functions (which exist but are discouraged), it’s because the parens are optional to call a function/method if there are no arguments.
- k__ 3y agoPhilosophically speaking, is it really hidden control flow if a function call just happens to look like a attribute access?
- dymk 3y agoI've only seen flow control used in the context of conditional branching, so if the function contains no branches, I don't see why it would. Hidden overhead or indirection, sure, but not necessarily flow control, for the same reason e.g. indirect pointer access isn't.
- PH95VuimJjqBqy 3y agofunction calls are, themselves, branches. underneath there is literally assembly to take current state, push it to the stack, then jump into another location in memory and start executing. And then when done, do the reverse. jump back to another memory location and pop everything back off the aforementioned stack and into registers.
- dymk 3y agoYes, but that's not a conditional branch, and that's the distinction I've always seen made for flow control versus indirection
- PH95VuimJjqBqy 3y agotry/catch/finally is also considered control flow and it's not conditional, although, unfortunately I've seen people use it as a control flow mechanism. interrupts are also control flow but, again, there are no conditionals there. control flow is about the order of execution, one common way to get there is using conditionals, but it's not the only way. Having said that, even if you disagree with Andrew's wording, the overarching idea remains. You always know explicitly if the flow changes.
- Akronymus 3y agotry/catch seems very conditional to me. If there is an error condition, jump to the error handling code. Or am I missing something?
- PH95VuimJjqBqy 3y agoI could also describe a JMP instruction as "if you got here, jump to there", but just because I can doesn't necessarily mean I should.
- epcoa 3y agoBut Try, catch and throw are in themselves not conditional, they are fancy gotos with bookkeeping. Those constructs don’t typically deal with conditions. However I think the notion that “flow control” has to do only with conditionals is not a common one. FWIW the definition on Wikipedia, which aligns with my experience is not this restrictive… the lowly goto is flow control. Basically anything that controls the program location is flow control.
- Akronymus 3y agoYeah, but raising the error is the conditional in there. Which, to me, makes the try catch conditional as well, but that may be a case of differing semantics. Yeah, flow control isn't just conditional jumps. You can kinda treat branchless code as a form of flow control as well.
- zdimension 3y agoWhen reading code in a low level setting you may want to know whether one line calls a function or simply reads a field from memory. Not that it would matter that much, but it's a valid point for some. Reading a field is usually expected to not induce any control flow
- gpderetta 3y ago> When reading code in a low level setting you may want to know whether one line calls a function or simply reads a field from memory. Unless you ditch optimizations completely, it is hard to know without looking at the generated asm. Of course you can make educated guesses.
- WalterBright 3y agoThe idea in D is to make the following unnecessary: struct S { int m_field; int field() { return m_field; } void field(int c) { m_field = x; } } just to future proof the field access. Don't bother with the access functions until they are actually needed.
- zozbot234 3y agoThe actual feature that languages should implement is lenses, prisms and optics which are like properties except made properly composable and enabling high-level optimizations, for a similar efficiency to "bare" field access.
- xigoi 3y agoI’ve never heard of those. Do you have a link explaining them?
- deepsun 3y agoI found a use for the overriding field access once, when there was a large data structure bit-packed into a byte array. I didn't really need to convert it to a different data structure, but to just extract some values, and pack it back to the byte array. So I overrode the field access that operated directly on the byte array. PS: It was in Kotlin, using @get/@set, but it doesn't matter for the philosophy.
- throwawaymaths 3y agoYes. That can affect performance and also cause spooky action at a distance. Suppose someone less careful put some code in the accessor function mutates global state. Do you want to be checking all of your objects all the time to see if they are doing something counterintuitive?
- Semaphor 3y agoInteresting that this is seen as a negative, C# has getters/setters that look like property access, but I don’t think I ever heard anyone complain about this.
- shp0ngle 3y agozig and c# each scratch a different itch.
- Semaphor 3y agoYeah, of course. But the issue would still be the same in this case.
- steveklabnik 3y agoWhile the issue is the same, context can make things different. In Ruby, I love proxy objects returned from accessors. In Rust, I wouldn't even support adding accessors to the language. Different goals and objectives.
- int_19h 3y agoC# inherited it from Delphi, so there's plenty of experience showing that this is not an issue in practice. Thing is, if you don't have accessor methods (or some equivalent syntactic sugar as in D) in a OO language, you end up with them anyway, just ad hoc like Java's get/set methods. And then you still have to think about which methods that look like they're pure queries might actually mutate shared state. If anything, I would argue that explicit accessors make it clearer because in e.g. C# you can't write a method that looks like a getter (but mutates state) by accidentally naming it as such. If someone made something a property, that's because they thought its semantics are property-like, which includes not mutating global state. Sure, people will still get that wrong occasionally, just as they run mutating "get" methods, but it is surprisingly rare.
- StreetChief 3y ago"If a tree falls in the woods and no one is around to hear it, does it still make a sound?" Attribute access is reading a value, invoking a function is different (as mentioned, using a stack, etc.), although it is certainly possible a function only reads and returns a value. All that to say my answer is yes, providing flow control mechanisms makes it flow control... and falling trees make a sound!