Grant Jacobs wrote:
Sounds silly, but I read the original message to mean "the identifier fnames was given but it doesn't fit here" (but it *does* fit there, so I got confused naturally enough!), rather than "I'm expecting a type identifier; I have no idea what fnames is". I should know by now to read all error messages as "you goofed; I have no idea what you're up to, here's my next-to-useless guess" ;-) Sorry, couldn't resist.
You want to distinguish known and unknown identifiers in the error messages to make things clearer (?)
unknown identifier `%s'
type name expected, `%s' given
?
{=>} points out the offending line of source. If this is truly the problem, then I presume there is no way of building a hierarchy of units in GPC at present? (In this case my safest strategy is to have every unit uses *all* the lower units directly, "just in case".
Yes, in a situation where each unit builds on all the previous ones, that's usually what one does.
Not necessarily: its what you do if you have no other choice!! :-) It forces all higher units to know the dependencies of the lower ones because you can't inherit the dependencies.
No, it doesn't. You only have to use the lower ones if you use some declaration from them. And if you do, you generally know that you do. (Well, I'm used to this, so it may appear more natural to me. But I've never had a big problem due to it ...)
Unless you compare units/modules and just consider that they just work from opposite views about how to restrict what is exported:
In units:
When uses is placed into an interface, all of the interface of used unit is propagated (inherited, etc.) unless the programmer restricts what is imported in the uses. [This is what I was hoping for, that is.]
In modules:
Nothing from a uses placed in an interface is exported (propagated, etc.) unless it is explicitly exported.
And in either case interfaces imported into implementation sections are hidden.
Modules are more explicit (and more pendantic!), but you also have to effectively state everything twice, once in a export statement and once just in the interface. If you have a lot to export, this must get to be a handful.
Yes, that's why GPC has `export Foo = all' as an extension (but referring only to the current module's interface, not to re-exporting). With the proposed extension `export Foo = all (Bar, ...)', it would be possible to export all from the current interface and some selected items from imported modules (such as some types used, as in your example) which I'd consider more reasonable than just re-exporting everything.
Once you have a means of obtaining just a specified portion of an interface,
This might be useful. Do you have any ideas for the syntax (in particular for units), other than an `export' clause (for modules)?
the module and unit approaches presented here would be equivalent (AFAICS), just coming from different angles. If you also added an 'export all' of a sub module (which I think you were mentioning the other day), they'd pretty much be exact alternatives. (Export is still in the docs as 'not yet implemented!)
Don't you mean `exports' (which is, AFIAK, for BP compatible "libraries", not to be confused with `export' for EP modules)?
This could be confusing and/or limiting: consider this case:
unit FileOps;
interface uses FnameUnit;
function WordCount( var fname: fnames ): integer ;
implementation { expected stuff... } end.
(Leave aside the fact most people would pass the opened file, not its name!) Assume fnames is defined in FnameUnit. Naturally, we want fnames exported for users of unit FileOps. Under the 'no export' scheme the other units need to "just know" that unit FnameUnit has the definition required and import FnameUnit when using FileOps. Under the alternative scheme other units can just 'uses FileOps' and get everything they need without have to know about any dependencies. The latter has its advantages... It'd be nicer if we had the option of only passing on just the things needed by FileOps should we want to, e.g. uses FnameUnit only ( fnames ); (in analogous fashion to how import specifies subsets.)
Doing the restriction on the import would be too ... well, restricting. ;-) You might need other stuff from FnameUnit within FileOps.
So, this case would fit the proposed `export Foo = all (Bar, ...)'.
For a similar reason, having a brute force compile-all option appeals to me (do the equivalent of --automake, but simply recompile all units you run into regardless of what status the units have [except that you'll want to detect circular dependencies!]).
You mean `--autobuild'?
As a general rule, everything after the first error message may or may not be accurate. This will always remain true, since no compiler can guess what you really mean when there is an error.
Like most people, I've been through that particular mill for a long time...! (But I'm still capable of confusing myself over an error message!) We'd all love a compiler that didn't do this, but "that'll be the day..." :-) (Maybe in my own programming language...;-) )
My suggestion: Implement a real AI first, then the rest will be trivial. ;-)
Frank