[M3devel] declaring/initializing variables "anywhere"
Jay
jay.krell at cornell.edu
Tue Aug 4 20:07:54 CEST 2015
But...Modula-3 already has this in VAR and WITH.
Every language has this for temporaries:
F1(F2() + F3())
Are these bad?
Too much explicit detail can actually get in the way of reading the code.
People also claim "just hover over the variable in IDE or debugger" which I don't buy. The tools always lag the language -- even if some don't, old tools remain in use.
"instant gratification" is also spun as "productivity" and "automatic maintenance" -- don't need to adjust redundant type declarations when things change, assuming compiler gets it right. Some people trust the deduction more than human, some don't.
- Jay
On Aug 4, 2015, at 9:42 AM, "Rodney M. Bates" <rodney_bates at lcwb.coop> wrote:
> You're poking at a really big peeve of mine. I do a lot of maintenance work. It usually
> involves finding one's way around in hundreds of thousands of lines of unfamiliar code.
> If you're exceptionally lucky, an eventual one-line change can be figured out after vetting
> a mere several tens of lines. Very often, it is more like a few hundreds, and not
> infrequently, even more.
>
> The average line of actively maintained code is written once and read something like
> seven times. (I don't remember where that number came from.) Speaking for myself,
> even most brand new code gets read at least seven times before it gets past my own testing,
> before it gets passed to anybody else to either use or further test. Moreover, the initial
> writer already has lots of context in his head that a maintainer has to ferret out.
>
> What I am leading to is that things should be *locally explicit*, far more than we usually
> see. Saving keystrokes once at initial writing time, at the cost of forcing the poor wretches
> who have to come along and figure it out later to constantly locate, open, scan another
> source file, every fourth token they read, is penny wise and pound foolish. It's classic
> case of instant-gratification immaturity. Ensuring a ton of aggravation later, to
> save an ounce of effort now. It's just plain laziness.
>
> (more below:)
>
> On 08/04/2015 05:02 AM, Jay K wrote:
>> I had:
>>
>>
>> PROCEDURE CompileProcAllocateJmpbufs (p: Proc) =
>> VAR module := Module.Current ();
>> alloca := Module.GetAlloca (module);
>> size := Module.GetJmpbufSize (module);
>
> So, coded like this, the poor schmuck who has to come along and figure this
> out will have to find Module.i3 and search it for declarations of Current,
> GetAlloca, and GetJmpbufSize, just to know what types we have. And possibly
> more steps, as with alloca, whose type, as we will find out, requires
> going to yet another source file CG.i3. It can be even worse, e.g.:
>
> VAR V := Ptr^.Field[I].method(X);
>
> You have to track down the type of Ptr, to find Field, to find the type of
> its elements, to find method, to find its result type.
>
> Sometimes it's obvious from identifier names, but more often, it is not, or at
> least only too vaguely for serious software work. Is a module denoted by an
> abstract type? An integer numbering of modules? something else? Very often,
> there are two or three different types that denote a module or whatever.
>
> (An aside: In C++, things often get dramatically worse when coders, overly
> enamored with cleverness for its own sake, define implicit type conversions
> among these, so the poor maintainer has even less idea what is going on.
> Moreover, the conversions could be declared anywhere in the tens of transitively
> #included files, and there is no path leading to them, only exhaustive search
> through all the files. And this possibility has to be considered for every
> single assignment and actual parameter.)
>
> Instead, I always code cases like this by putting both the type and the initializer
> in the declaration:
> VAR module : Module.T := Module.Current ();
>
> I even often do it this way when the initializer is a literal. For one thing,
> I may want a subrange for the type of the variable.
>
> The exception is when the initializer itself also names the type. It's shorter,
> but at no loss of explicitness.
>
> VAR rec := SomeInterface.SomeType { 0 , NIL , FALSE };
>
>> try_count := p.try_count;
>> BEGIN
>>
>>
>> which is fairly nice and elegant.
>> I like the static type inference.
>>
>>
>> but p could be NIL so I need like:
>>
>>
>> PROCEDURE CompileProcAllocateJmpbufs (p: Proc) =
>> VAR module: Module.T;
>> alloca: CG.Proc;
>> size: CG.Var;
>> try_count: INTEGER;
>> BEGIN
>> IF p = NIL THEN RETURN END;
>> module := Module.Current ();
>> alloca := Module.GetAlloca (module);
>> size := Module.GetJmpbufSize (module);
>> try_count := p.try_count;
>>
>>
>> double the lines, and a need to state types that I didn't have to state before,
>
> This will save wasted computation calling the functions, if it turns out p=NIL.
> Depending on the purpose of the code. In some code, I care about efficiency
> at this level.
>
>>
>> OR I can use WITH to get the "best" of both, but implied extra indentation.
>
> If I were to propose any language change at all, it would be to allow a WITH
> binding to optionally specify the type too, for exactly the same reasons.
>
> WITH w : T = Var.method(x) DO ...
>
> Many a WITH statement has been far too hard to read, requiring the side trips of
> checking other source files to see what this value really is.
>
>
>
>>
>>
>> Pretty much all other mainstream languages in use today,
>> except C89, are "better" than this, they all let you
>> both delay local variable declaration until arbitrarily
>> into a function, but with implying that you should indent further,
>> or close an extra block.
>
> To be clear, I definitely do not advocate allowing declarations and statements
> to be arbitrarily mixed in a block, BUT... if we did it, at least the decls
> would be syntactically explicit with a VAR, and we would not have to "define"
> our language with words like "if it looks like a declaration...".
>
>>
>> Most mainstream languages also share Modula-3's type inference
>> and let you omit the type, except C.
>>
>>
>> Can we update Modula-3 here somehow?
>>
>>
>> Or just use "with"?
>>
>>
>> Proposals for a syntax that works well with the existing language and compiler?
>>
>>
>> Thank you,
>> - Jay
>>
>>
>>
>>
>> _______________________________________________
>> M3devel mailing list
>> M3devel at elegosoft.com
>> https://mail.elegosoft.com/cgi-bin/mailman/listinfo/m3devel
>
> --
> Rodney Bates
> rodney.m.bates at acm.org
More information about the M3devel
mailing list