December 08, 2013
On Sat, Dec 07, 2013 at 08:07:08PM -0800, Walter Bright wrote:
> On 12/7/2013 6:07 PM, Manu wrote:
> >At least in certain types of code, which perhaps you don't spend an awful lot of time writing?
> 
> Funny thing about that. Sometimes I'll spend all day on a piece of code, then check it in. I'm surprised that the diffs show my changes were very small.

At my job, we actually take pride in minimizing our diffs. My manager once mentioned that sometimes, it could take days to produce a one-line diff, because it takes that long to (1) find the bug and (2) figure out the least intrusive way to fix it.

Diffs that are obviously larger than necessary (esp. with frivolous whitespace changes) will often be rejected during the code review process, or, at the very least, the submitter will be told to rework his diffs to avoid touching stuff unrelated to the actual code fix. (Sadly, this isn't done during feature branch merges, and so a lot of poor code tends to creep in through feature branches. Sigh. Can't have your cake and eat it too, I guess.)


> I suppose I spend far more time thinking about code than writing it.

When I was in school, I was taught to do that. I think I take it to the extremes, though. Sometimes I'd think about a piece of code for months before actually writing it because I just can't sort out all the details in my head.  Often I have to force myself to just start writing the code, and then the details I was worried about tend to work themselves out quite nicely.  Now obviously, starting to write code without the slightest idea about what kind of algorithms should be used, etc., is a bad idea, and tends to lead to bad, non-maintainable code. But thinking about it too much leads to non-productivity. So there's a balance to be struck somewhere, but I'm still trying to figure out where that is.  :)


T

-- 
"A one-question geek test. If you get the joke, you're a geek: Seen on a California license plate on a VW Beetle: 'FEATURE'..." -- Joshua D. Wachs - Natural Intelligence, Inc.
December 08, 2013
On 8 December 2013 14:07, Walter Bright <newshound2@digitalmars.com> wrote:

> On 12/7/2013 6:07 PM, Manu wrote:
>
>> At least in certain types of code, which perhaps you don't spend an awful
>> lot of
>> time writing?
>>
>
> Funny thing about that. Sometimes I'll spend all day on a piece of code, then check it in. I'm surprised that the diffs show my changes were very small.
>
> I suppose I spend far more time thinking about code than writing it.


Precisely my point. I have a strong suspicion that you've spent many consecutive years now writing code in that way.

I don't think the job of a systems/tech programmer is a close approximation
of probably the vast majority of modern programmer's days. I think the bulk
majority of programmers are employed to bash out code and string things
together to produce their particular product. Be it on the web, or some
application, or whatever. I think 'most' code is the stringing together of
libraries in ways specific to the project requirements, and that sort of
code _really_ benefits from powerful tooling.
Also most projects have unstable goal-posts, which leads to inevitable
refactoring of your project whenever project requirements change.

Current D tooling offers... well, barely anything. VisualD and the like are
good first steps. We basically have syntax highlighting, and to a very
limited degree, suggestion + auto-completion. I couldn't (**wouldn't) work
without those as a minimum, but these only begin to scratch the surface
though when compared to say Java and C# tooling (examples I'm familiar
with).
I've often wondered what the DMD front end could offer if it was properly
extracted into a library with a well designed API for tooling projects to
interact with.
One of the hard problems is that you want tools to make proper suggestions
and highlight errors and stuff in realtime, on code as it's being typed,
which doesn't actually compile due to incomplete expressions or errors.
I suspect systems like the CTFE system, which is able to perform semantic
analysis (and execution) on subsets of code, ie, it seems it can evaluate
expressions even where there are compile errors in surrounding code.

That old Eclipse tool that offered a 'intermediate' view that unfolded mixins and template expansion was awesome. I would find that so useful!


December 08, 2013
Am Sun, 08 Dec 2013 05:19:53 +0100
schrieb "Jason den Dulk" <public2@jasondendulk.com>:

> One think I have discovered is that Phobos introduces "junk code" into executables. One time I did an experiment. I copied the bits of Phobos that my program used into a separate file and imported that instead of the Phobos modules. The resultant executable was half the size (using -release, -inline, -O and "strip" in both cases). For some reason, Phobos was adding over 250KB of junk code that strip could not get rid of.
> 
> Regards
> Jason

Strip doesn't remove dead code, but sections in the executable that aren't required for running the program, like symbol names or debugging information. That said all code is merged into a single .text section by the linker and cannot be tangled by strip at all.

To remove unreferenced functions, use:
gdc -ffunction-sections -Wl,--gc-sections
That will create a single section for every function (instead
of one section per module as far as I understand it) and tell
the linker to remove any section that is not referenced.

-- 
Marco

December 08, 2013
Am Sat, 7 Dec 2013 21:35:39 -0800
schrieb "H. S. Teoh" <hsteoh@quickfur.ath.cx>:

> On Sun, Dec 08, 2013 at 03:01:03AM +0100, digitalmars-d-bounces@puremagic.com wrote:
> > On Sunday, 8 December 2013 at 01:59:15 UTC, Walter Bright wrote:
> > >But when I talk about refactoring, I mean things like changing data structures and algorithms. Renaming things is pretty far over on the trivial end, and isn't going to help your program run any faster.
> > 
> > Well, I was just so surprised by your answer that I was looking for common ground :-)
> 
> OTOH, I was quite confused the first time somebody talked about "refactoring" to refer to variable renaming. To me, refactoring means reorganizing your code, like factoring out common code into separate functions, and moving stuff around modules, and substituting algorithms; the kind of major code surgery where you go through every line (or every block) and re-stitch things together in a new (and hopefully cleaner) way.  Variable renaming sounds almost like a joke to me in comparison. I was quite taken aback that people would think "variable renaming" when they say "refactoring", to be quite honest.
> 
> Or maybe this is just another one of those cultural old age indicators? Has the term "refactoring" shifted to mean "variable renaming" among the younger coders these days? Genuine question. I'm baffled that these two things could even remotely be considered similar things.
> 
> 
> T

IDEs offer symbol renaming in their catalog of automated
refactorings. Often a single key press (like F2) makes
safely renaming a symbol to more descriptive name so easy that
it became the #1 most used refactoring. So "refactoring"
refers to that menu with automated refactorings and most
probably to the rename command :)

-- 
Marco

December 08, 2013
On 12/08/2013 06:35 AM, H. S. Teoh wrote:
> ...
>
> Or maybe this is just another one of those cultural old age indicators?
> Has the term "refactoring" shifted to mean "variable renaming" among the
> younger coders these days? Genuine question. I'm baffled that these two
> things could even remotely be considered similar things.
>
>
> T
>

"Refactoring" means changing code without changing its functional behaviour.
December 08, 2013
On Sunday, 8 December 2013 at 05:27:12 UTC, H. S. Teoh wrote:
> Once I hacked up a script  (well, a little D program :P) that
> disassembles D executables and builds a reference graph of
> its symbols.

Do you still have that somewhere? I've never attempted such a thing and would like to see what it entailed.
December 08, 2013
On 08/12/13 06:25, H. S. Teoh wrote:
> Yeah, this part bothers me too. Once I hacked up a script (well, a
> little D program :P) that disassembles D executables and builds a
> reference graph of its symbols. I ran this on a few small test programs,
> and was quite dismayed to discover that the mere act of importing
> std.stdio (for calling writeln("Hello World");) will introduce symbols
> from std.complex into your executable, even though the program has
> nothing to do with complex numbers. These symbols are never referenced
> from main() (i.e., the reference graph of the std.complex symbols are
> disjoint from the subgraph that contains _Dmain), yet they are included
> in the executable.

Do you have any idea why the std.complex symbols were pulled in, i.e. what dependencies were responsible?  The only module that I'm aware of that imports std.complex is std.numeric, which is itself only imported by std.parallelism and std.random.

Are you sure it's not just the whole of Phobos being built in statically because you don't strip the binary?
December 08, 2013
On Friday, 6 December 2013 at 22:20:19 UTC, Walter Bright wrote:
>
> "there is no way proper C code can be slower than those languages."
>
>   -- http://www.reddit.com/r/programming/comments/1s5ze3/benchmarking_d_vs_go_vs_erlang_vs_c_for_mqtt/cduwwoy
>
> comes up now and then. I think it's incorrect, D has many inherent advantages in generating code over C:
>
> 1. D knows when data is immutable. C has to always make worst case assumptions, and assume indirectly accessed data mutates.
>
> 2. D knows when functions are pure. C has to make worst case assumptions.
>
> 3. Function inlining has generally been shown to be of tremendous value in optimization. D has access to all the source code in the program, or at least as much as you're willing to show it, and can inline across modules. C cannot inline functions unless they appear in the same module or in .h files. It's a rare practice to push many functions into .h files. Of course, there are now linkers that can do whole program optimization for C, but those are kind of herculean efforts to work around that C limitation of being able to see only one module at a time.
>
> 4. C strings are 0-terminated, D strings have a length property. The former has major negative performance consequences:
>
>     a. lots of strlen()'s are necessary
>
>     b. using substrings usually requires a malloc/copy/free sequence
>
> 5. CTFE can push a lot of computation to compile time rather than run time. This has had spectacular positive performance consequences for things like regex. C has no CTFE ability.
>
> 6. D's array slicing coupled with GC means that many malloc/copy/free's normally done in C are unnecessary in D.
>
> 7. D's "final switch" enables more efficient switch code generation, because the default doesn't have to be considered.

From this list only (7) is a valid point. All the others can be trivially dealt with whole program optimization (1,2,3) or coding conventions (4,5,6) (always pass a (char*, len) pair around for efficient slicing). Interestingly, things that are encouraged in Ada (this is an array of integers of range 0..30, see value range propagation) are much harder to recompute with whole program optimization and D lacks them.
December 08, 2013
On 08/12/13 01:46, Manu wrote:
> True as compared to C, but I wouldn't say this is true in general.

Let's give praise where praise is due -- with D, the ease of refactoring is _entirely_ down to the language.  You get it without needing an IDE to support you.  It's a very impressive achievement.

That said, this is a _positive_ reason for pursuing the other tools -- imagine how much better it could be, with IDE refactoring support and other such benefits.
December 08, 2013
On Sunday, 8 December 2013 at 10:11:20 UTC, Joseph Rushton Wakeling wrote:
> On 08/12/13 06:25, H. S. Teoh wrote:
>> Yeah, this part bothers me too. Once I hacked up a script (well, a
>> little D program :P) that disassembles D executables and builds a
>> reference graph of its symbols. I ran this on a few small test programs,
>> and was quite dismayed to discover that the mere act of importing
>> std.stdio (for calling writeln("Hello World");) will introduce symbols
>> from std.complex into your executable, even though the program has
>> nothing to do with complex numbers. These symbols are never referenced
>> from main() (i.e., the reference graph of the std.complex symbols are
>> disjoint from the subgraph that contains _Dmain), yet they are included
>> in the executable.
>
> Do you have any idea why the std.complex symbols were pulled in, i.e. what dependencies were responsible?  The only module that I'm aware of that imports std.complex is std.numeric, which is itself only imported by std.parallelism and std.random.
>
> Are you sure it's not just the whole of Phobos being built in statically because you don't strip the binary?


std.stdio -> std.algorithm -> std.random -> std.numeric -> std.complex.