Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2016-02

Please someone explain this to me

53 messages · 17 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Anthony Walter

I really don't like the include files with Lazarus and Free Pascal for the following reason:

How the **** am I supposed to know which file is including an include file?

Often times I am trying to find a function or class or some other identifier and I search files on disk for the name. Then it turns out the identifier is in some include file. Often the include file doesn't have any information to which unit it belongs and I am then forced to search further for other files which reference the include file. It's a mess.

In this issue http://mantis.freepascal.org/view.php?id=29599 Juha is asking how I was able to compile my patch without using the dynlibs unit. Sure enough I am not using the dynlibs unit, but on my system it compiles. When I control click the LoadLibrary identifier in my Unity patch, Lazarus brings up an include file with LoadLibtary declared, but I have no idea which unit is including it (remember I'm not using unit dynlibs).

So my question is, how do the rest of you deal with include files and locating the unit including them? And also can this system for including files be better implemented, for example by some IDE feature to figure this out for you and displaying the "owning" units.

Reply by email

Ralf Quint
to Anthony Walter
Anthony Walter wrote 26 lines
I really don't like the include files with Lazarus and Free Pascal for the following reason: How the **** am I supposed to know which file is including an include file? Often times I am trying to find a function or class or some other identifier and I search files on disk for the name. Then it turns out the identifier is in some include file. Often the include file doesn't have any information to which unit it belongs and I am then forced to search further for other files which reference the include file. It's a mess. In this issue http://mantis.freepascal.org/view.php?id=29599 Juha is asking how I was able to compile my patch without using the dynlibs unit. Sure enough I am not using the dynlibs unit, but on my system it compiles. When I control click the LoadLibrary identifier in my Unity patch, Lazarus brings up an include file with LoadLibtary declared, but I have no idea which unit is including it (remember I'm not using unit dynlibs). So my question is, how do the rest of you deal with include files and locating the unit including them? And also can this system for including files be better implemented, for example by some IDE feature to figure this out for you and displaying the "owning" units.

It seems to me as if you are approaching the problem from the wrong end, which has your search end up in the include file instead of the associated unit.

I had only a cursory look at your problem and it seems you just went straight to the Linux related LoadLibrary function instead of indeed using the dynlibs unit, which exist for the purpose of creating a cross-platform way of using dynamically loaded libraries (hence the name). You seem to just ignore the fact that this is a highly OS depended functionality and seemed to have taken interest only in the Linux related part of what ever your initial problem is/was and used that portion of the code in stead of making use of the dynlibs unit.

Ralf

---
This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus

Reply by email

Anthony Walter
to Ralf Quint

Ralf,

A couple of points.

1) As I explained there are times when I, and probably other people as well, need to find the declaration of a function, constant, record, or some other identifier. We may not know if the function even exists or has been declared in Pascal, for example when attempting to use specific APIs dependent on some external library. In those case my approach is often to search (grep) files under either my lazarus or fpc folder. If there is some better way please to find these identifiers, which are not in the help systems, please let me know.

Continuing, when I do locate these files often they are in include files, and it's at that point where the problem I described occurs. That is, trying to locate what file is including the ".inc" file so that I can add the necessary package and units to my project.

And ...

2) In your cursory look you mention I seemed to have only taken interest in a Linux related part. Well the patch I've created deals with Ubuntu's new Unity application indicators which prevent TTrayIcon from working. This is a problem specific to Ubuntu Unity (a Linux distribution), so of course the fix is going to be highly OS dependent.

Reply by email

Vojtěch Čihák
to Anthony Walter: I really don't like the include files with Lazarus and Free Pascal for the following…

There exists IDE directive
{%MainUnit ***.pas}
and include files should contain it. But I don't know if there are more units containing the same include file.  
V.
______________________________________________________________

Show quoted text 5 lines
Od: Anthony Walter Komu: "FPC-Pascal users discussions" Datum: 10.02.2016 00:06 Předmět: [fpc-pascal] Please someone explain this to me

I really don't like the include files with Lazarus and Free Pascal for the following reason:How the **** am I supposed to know which file is including an include file?Often times I am trying to find a function or class or some other identifier and I search files on disk for the name. Then it turns out the identifier is in some include file. Often the include file doesn't have any information to which unit it belongs and I am then forced to search further for other files which reference the include file. It's a mess.In this issue http://mantis.freepascal.org/view.php?id=29599 <http://mantis.freepascal.org/view.php?id=29599> Juha is asking how I was able to compile my patch without using the dynlibs unit. Sure enough I am not using the dynlibs unit, but on my system it compiles. When I control click the LoadLibrary identifier in my Unity patch, Lazarus brings up an include file with LoadLibtary declared, but I have no idea which unit is including it (remember I'm not using uni t dynlibs).So my question is, how do the rest of you deal with include files and locating the unit including them? And also can this system for including files be better implemented, for example by some IDE feature to figure this out for you and displaying the "owning" units.

----------

Reply by email

Sven Barth
to Ralf Quint: It seems to me as if you are approaching the problem from the wrong end, which has your…
"Ralf Quint" wrote
On 2/9/2016 2:58 PM, Anthony Walter wrote: > > I really don't like the include files with Lazarus and Free Pascal for

the following reason:

> > How the **** am I supposed to know which file is including an include

file?

> > Often times I am trying to find a function or class or some other

identifier and I search files on disk for the name. Then it turns out the identifier is in some include file. Often the include file doesn't have any information to which unit it belongs and I am then forced to search further for other files which reference the include file. It's a mess.

asking how I was able to compile my patch without using the dynlibs unit. Sure enough I am not using the dynlibs unit, but on my system it compiles. When I control click the LoadLibrary identifier in my Unity patch, Lazarus brings up an include file with LoadLibtary declared, but I have no idea which unit is including it (remember I'm not using unit dynlibs).

> > So my question is, how do the rest of you deal with include files and

locating the unit including them? And also can this system for including files be better implemented, for example by some IDE feature to figure this out for you and displaying the "owning" units.

> It seems to me as if you are approaching the problem from the wrong end,

which has your search end up in the include file instead of the associated unit.

I had only a cursory look at your problem and it seems you just went

straight to the Linux related LoadLibrary function instead of indeed using the dynlibs unit, which exist for the purpose of creating a cross-platform way of using dynamically loaded libraries (hence the name). You seem to just ignore the fact that this is a highly OS depended functionality and seemed to have taken interest only in the Linux related part of what ever your initial problem is/was and used that portion of the code in stead of making use of the dynlibs unit.

Since 3.0.0 the DynLibs unit is only needed to initialize the dynamic library manager on platforms that don't have it in System (like Windows does). The related functions (e.g. LoadLibrary() ) have been moved to System as that functionality is required both for dynamic packages and delay loading. (Note: DynLibs still contains the functions, but they forward to the System ones).

Regards,
Sven

Reply by email

Marc Santhoff
to Anthony Walter: A couple of points. 1) As I explained there are times when I, and probably other people as
Anthony Walter wrote 12 lines
Ralf, A couple of points. 1) As I explained there are times when I, and probably other people as well, need to find the declaration of a function, constant, record, or some other identifier. We may not know if the function even exists or has been declared in Pascal, for example when attempting to use specific APIs dependent on some external library. In those case my approach is often to search (grep) files under either my lazarus or fpc folder. If there is some better way please to find these identifiers, which are not in the help systems, please let me know.

If you are using Lazarus:
- put the cursor inside the indentifier
- use right mouse key
- klick "find declaration of ..." or use key combination ALT-UpArrow

When on the console, I don't know. Searching would have to be done with the OS and target cpu in mind, because in many cases that's what switches included files. I did not try yet.

There hsa been a thread on the lazaurs list lately, handling the topic of "navigating huge files" or similar. There is a lot of info about what lazarus can do for you regarding search and navigation.

Marc Santhoff

Reply by email

Graeme Geldenhuys
to Vojtěch Čihák: There exists IDE directive {%MainUnit ***.pas} and include files should contain it. But I…
Vojtěch Čihák wrote
There exists IDE directive {%MainUnit ***.pas} and include files should contain it.

That is not an include file requirement, plus that functionality is a Lazarus-only trick. Any other editor and the FPC compiler sees that as a simple code comment. Plus not all include files include that information
- in fact most I've seen don't.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp

Reply by email

Anthony Walter
to Marc Santhoff: If you are using Lazarus: - put the cursor inside the indentifier - use right mouse key -…

Marc,

Your suggestions only work if a unit declaring the function is in your uses clauses. In the scenario I described that is clearly not the case.

Additionally, and in a different scenario, when the identifier IS defined and several units are in the uses clause the goto declaration can jump to an include file without any information pertaining to which of the units is including the file. To the best of my knowledge there isn't a straight forward way to figure this out, unless the author add that text to a comment in the included file which often is not the case.

Reply by email

Sven Barth
to Anthony Walter
"Anthony Walter" wrote
Marc, Your suggestions only work if a unit declaring the function is in your

uses clauses. In the scenario I described that is clearly not the case.

Additionally, and in a different scenario, when the identifier IS defined

and several units are in the uses clause the goto declaration can jump to an include file without any information pertaining to which of the units is including the file. To the best of my knowledge there isn't a straight forward way to figure this out, unless the author add that text to a comment in the included file which often is not the case.

You can alternatively simply try F1, at least as long as you know the identifier. That will either take you to the help or it will open the Code Browser which will search for the identifier.

This was also discussed in the following thread on the Lazarus mailing list:
http://lists.lazarus.freepascal.org/pipermail/lazarus/2014-February/085631.html

Maybe this will help in at least some situations :)

Regards,
Sven

Reply by email

Marc Santhoff
to Anthony Walter: Your suggestions only work if a unit declaring the function is in your uses clauses. In…
Anthony Walter wrote 11 lines
Marc, Your suggestions only work if a unit declaring the function is in your uses clauses. In the scenario I described that is clearly not the case. Additionally, and in a different scenario, when the identifier IS defined and several units are in the uses clause the goto declaration can jump to an include file without any information pertaining to which of the units is including the file. To the best of my knowledge there isn't a straight forward way to figure this out, unless the author add that text to a comment in the included file which often is not the case.

What use case do you plan to handle?

If things are so weird as they are reagrding your requirements then build up a search index, there are many crawlers, search engines and the like available.

Marc Santhoff

Reply by email

leledumbo
to Anthony Walter: I really don't like the include files with Lazarus and Free Pascal for the following…
So my question is, how do the rest of you deal with include files and

locating the unit including them?

I don't know what "deal" here refers to, so I can't answer that. I seldom use include files except when I have to deal with what the compiler/rtl face: platform dependent implementation of certain API in a platform independent unit. Sometimes I use it to have multiple classes in the same unit but I want each class to be in their own (include) file. Condition compilation is used to have interface and implementation in one file and is included twice in each respective section in the unit.

I use grep to locate the units including them (the directive is either {$I or {$INCLUDE, no other possibilites), nothing special or complex.

And also can this system for including files be better implemented, for example by some IDE feature to figure this out for you and displaying the "owning" units.

For IDE, it's up to them of course. For instance, Lazarus uses its own codetools for source navigation, nothing from the compiler, if that's what you mean. It already indexes identifiers where they reside, it won't be difficult to index all {$I and {$INCLUDE as well. It's just since include files may be included by more than one files, the navigation must be altered somehow.

View this message in context: http://free-pascal-general.1045716.n5.nabble.com/Please-someone-explain-this-to-me-tp5724028p5724039.html Sent from the Free Pascal - General mailing list .

Reply by email

Juha Manninen
to Vojtěch Čihák: There exists IDE directive {%MainUnit ***.pas} and include files should contain it. But I…
Vojtěch Čihák wrote 5 lines
There exists IDE directive {%MainUnit ***.pas} and include files should contain it.

Yes, that is the solution for Anthony's problem. Most include files used by LCL units have it but FPC libraries may not. When the directive is set, Lazarus IDE always knows how to jump between interface in Pascal unit and implementation in an include file.
The {%...} directive is a comment in other contexts and can be used safely.

But I don't know if there are more units containing the same include file.

When a big Pascal unit is split into include files then an include file is referred from one place only.
The directive is not meant for generic include files.

The original question about dynlibs remains. I understood with FPC 3.0 it is not needed but I could not compile without it. This has nothing to do with cross-platform code. I am testing with Xubuntu + GTK2 as the code is part of LCL-GTK2.
Actually I still have the RC1 version here:
$ fpc
Free Pascal Compiler version 3.0.0rc1 [2015/08/07] for x86_64 ...
Could there be such a difference between RC1 and the release? Anyway, I added dynlibs there. It is needed at least by FPC 2.6.4 which we still support for some time.
Ubuntu people, please test the Unity TTrayIcon feature. I have only tested it does not break LCL-GTK2 in other systems. I will install Ubuntu + Unity soon.

Juha

Reply by email

Sven Barth
to Juha Manninen
"Juha Manninen" wrote
On Wed, Feb 10, 2016 at 2:01 AM, Vojtěch Čihák
Show quoted text 12 lines
> There exists IDE directive > > {%MainUnit ***.pas} > > and include files should contain it. Yes, that is the solution for Anthony's problem. Most include files used by LCL units have it but FPC libraries may not. When the directive is set, Lazarus IDE always knows how to jump between interface in Pascal unit and implementation in an include file. The {%...} directive is a comment in other contexts and can be used

safely.

What about include files included by other include files?

> But I don't know if there are more units containing the same include

file.

Show quoted text 19 lines
When a big Pascal unit is split into include files then an include file is referred from one place only. The directive is not meant for generic include files. The original question about dynlibs remains. I understood with FPC 3.0 it is not needed but I could not compile without it. This has nothing to do with cross-platform code. I am testing with Xubuntu + GTK2 as the code is part of LCL-GTK2. Actually I still have the RC1 version here: $ fpc Free Pascal Compiler version 3.0.0rc1 [2015/08/07] for x86_64 ... Could there be such a difference between RC1 and the release? Anyway, I added dynlibs there. It is needed at least by FPC 2.6.4 which we still support for some time. Ubuntu people, please test the Unity TTrayIcon feature. I have only tested it does not break LCL-GTK2 in other systems. I will install Ubuntu + Unity soon.

I must check whether I had done that change before or after the branch... On non-Windows systems you'll need to include dynlibs at least in the main project anyway as it is needed to initialize the library manager (just like cthreads and cwstring).

Regards,
Sven

Reply by email

Marco van de Voort
to Juha Manninen: Yes, that is the solution for Anthony's problem. Most include files used by LCL units…

In our previous episode, Juha Manninen said:
[ Charset UTF-8 unsupported, converting... ]

Show quoted text 9 lines
On Wed, Feb 10, 2016 at 2:01 AM, Vojt?ch ?ih?k wrote: > There exists IDE directive > > {%MainUnit ***.pas} > > and include files should contain it. Yes, that is the solution for Anthony's problem. Most include files used by LCL units have it but FPC libraries may not.

I think it would be good to add that to most FPC inc files in rtl and fcl too.

Most usage is straightforward, and can be solved using the directive. Some, like ptypes.inc are more complicated.

I'll see if I can add some directives in the coming weeks.

Reply by email

Michael Van Canneyt
to Juha Manninen
Juha Manninen wrote
On Wed, Feb 10, 2016 at 4:09 PM, Sven Barth wrote: > What about include files included by other include files? Ok, that is a nasty situation. I think it should be avoided.

Happens regularly in the RTL units, though.

Michael.

Reply by email

Anthony Walter
to Sven Barth

Thanks everyone for taking notice in the include file problem. I'm note sure about other people, but to me its a problem that sometimes limits me from following the source code. Ideally there should be one file per unit with an interface section and an implementation section and no include files, but I can understand how the multi-platform features of FPC and Lazarus necessitate using include files.

I think the thing is I can't help but feel there should be a better system for organizing implementations for different systems. For example, many units use include file in their interface sections. Is that really necessary and what does that achieve other than making it more difficult to understand what's being declared? And could the IDE be enhanced to should which unit is ultimately including a file? Obviously the CodeTools already knows, it was able to deduce the identifier exists and that it has a declaration by looking through the units in the uses clause in the current unit. Couldn't something therefore display the unit name in IDE, possibly in the include file's source code tab (e.g. system.pas - dynlibh.inc)?

Thanks for considering this as an issue.

Reply by email

Michael Van Canneyt
to Anthony Walter
Anthony Walter wrote 6 lines
Thanks everyone for taking notice in the include file problem. I'm note sure about other people, but to me its a problem that sometimes limits me from following the source code. Ideally there should be one file per unit with an interface section and an implementation section and no include files, but I can understand how the multi-platform features of FPC and Lazarus necessitate using include files.

You just need to look at the system or sysutils units from recent delphis to see why include files are the better option, if you consider that FPC has far more platforms to support.

That said, the MainUnit directive is easily added to the sources.

Michael.

Reply by email

Juha Manninen
to Anthony Walter: Thanks everyone for taking notice in the include file problem. I'm note sure about other…
Anthony Walter wrote 6 lines
And could the IDE be enhanced to should which unit is ultimately including a file? Obviously the CodeTools already knows, it was able to deduce the identifier exists and that it has a declaration by looking through the units in the uses clause in the current unit. Couldn't something therefore display the unit name in IDE, possibly in the include file's source code tab (e.g. system.pas - dynlibh.inc)?

Maybe you did not fully understand what the MainUnit directive does. It allows you to jump between the Pascal unit and the include file in any situation, just as if they were one single file. It works also if you opened first an include file from a search window. The other way around (unit -> include file) it works even without a MainUnit directive.
Thus, Lazarus editor fully understands include files unlike Delphi' editor.

In other words you can always do Ctrl-Shift-Up in a method / function and it does the right thing.
You don't need to worry about if your cursor is on a unit or include file source.

Juha

Reply by email

Anthony Walter
to Juha Manninen

Juha,

Okay then, maybe everyone should make a mental note and remember add the MainUnit directive to the include files they are editing if it doesn't already exist.

But to ask again, what's the purpose of using include files for the interface section of units when most everything in the interface sections remain unchanged among different platforms? Surely we can move all those the parts back to the unit interface sections. Perhaps if you want to match up a single interface declaration with a several include implementations, I can see that as one method of organization, but wouldn't {$region names} in the interface declarations {$endregion} would be an improvement over many interface section include files? This way I can actually scroll through the interface, ctrl+f through the interface, and not be forced to ctrl+enter on interface section includes to see what is being declared.

Reply by email

Anthony Walter
to Anthony Walter

Oh and when the MainUnit directive is included at the top of an include file, how does this affect include files where the declaration is another include files, or include files which next other include files?

Reply by email

Mattias Gaertner
to Sven Barth: safely. What about include files included by other include files? file. I must check…
Show quoted text 6 lines
Sven Barth hat am 10. Februar 2016 um 15:09 geschrieben: [...] > The {%...} directive is a comment in other contexts and can be used safely. What about include files included by other include files?

That is no problem for the MainUnit directive.
The directive tells the codetools the default start file of the scattered unit. If the IDE has parsed a unit which uses the include file, the MainUnit directive is ignored.
If a file is included by multiple units, you can give a common unit.

Basically it is just a convenient fallback.

Mattias

Reply by email

Graeme Geldenhuys
to Michael Van Canneyt: You just need to look at the system or sysutils units from recent delphis to see why…
Michael Van Canneyt wrote
You just need to look at the system or sysutils units from recent delphis to see why include files are the better option,

As someone that doesn't have access to recent Delphi versions, would you mind sharing a small example if you can. I'm not at all surprised by your comment though. From the messages I have seen about Delphi these days, not many customers are happy with Delphi's "progress". It sounds like every release is more like a patch-job to get the next set of bullet points filled for the next release. No regard for the language or quality control.

Regards,
- Graeme -

Reply by email

Graeme Geldenhuys
to Anthony Walter: Thanks everyone for taking notice in the include file problem. I'm note sure about other…
Anthony Walter wrote
I think the thing is I can't help but feel there should be a better system for organizing implementations for different systems.

Often some clever usage of design patterns can help, but more often than not, using include files are just a faster and easier solution to implement. Make no mistake, include files (when used correctly) is a pretty powerful option too.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp

Reply by email

Dmitry Boyarintsev
to Graeme Geldenhuys: As someone that doesn't have access to recent Delphi versions, would you mind sharing a…

On Wed, Feb 10, 2016 at 3:32 PM, Graeme Geldenhuys <

Show quoted text 9 lines
wrote: On 2016-02-10 19:20, Michael Van Canneyt wrote: > You just need to look at the system or sysutils units from recent delphis to > see why include files are the better option, As someone that doesn't have access to recent Delphi versions, would you mind sharing a small example if you can.

It would be odd if they're using includes heavily.

It feels like namespaces should've resolved the problem. Thus includes are replaced by namespaces, since it **should** keep unit-like code structure.

thanks,
Dmitry

Reply by email

Graeme Geldenhuys
to Juha Manninen: Maybe you did not fully understand what the MainUnit directive does. It allows you to…
Juha Manninen wrote
Thus, Lazarus editor fully understands include files unlike Delphi' editor.

The knock-on affect of include files, is that pascal parsers are much more complex to write. Luckily we already have quite a few pascal parsers available, which already work with include files and search paths etc.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp

Reply by email

Tomas Hajny
to Anthony Walter
Anthony Walter wrote
What about the interface section includes and {$region} option I described. Does anyone care to discuss that option? Please go back a few messages and read what I wrote.

I don't get your $region idea, but as a maintainer of one of the FPC targets, I can tell you that there are differences also in the interface sections. Just as an example - unit system needs to combine parts which are completely common (solved using common include files) with parts which are platform-specific (take e.g. the DirectorySeparator or LineEnding as examples). Sometimes there are differences at the target level, sometimes at platform level, sometimes it makes sense to use a common include file for a set of targets sharing a common set of characteristics (various MS Windows targets or Unix targets) in order to simplify the maintenance, etc. Trying to cover that in one common place would result in something completely unreadable and unmaintainable - actually much worse compared to the current situation.

Tomas

Reply by email

Marco van de Voort
to Tomas Hajny

In our previous episode, Tomas Hajny said:

Show quoted text 6 lines
at platform level, sometimes it makes sense to use a common include file for a set of targets sharing a common set of characteristics (various MS Windows targets or Unix targets) in order to simplify the maintenance, etc. Trying to cover that in one common place would result in something completely unreadable and unmaintainable - actually much worse compared to the current situation.

Indeed, the include stuff is not a linear thing. Generic Unix includes include (are parameterized) by target specific includes like the earlier named ptypes.inc.

And then you get to the bit that the syscall targets are switchable to libc etc.

The original design document for the *nix RTL (originally (c) dec 2002) already had a section about why includefiles:

http://www.stack.nl/~marcov/unixrtl.pdf

One thing to particularly highlight: many *nix includefiles are used in the /implementation/ of units below the baseunix unit level, while they only become public on the unixtype/baseunix level and below (see pic in above doc)

Reply by email

Sven Barth
to Anthony Walter: Okay then, maybe everyone should make a mental note and remember add the MainUnit…
"Anthony Walter" wrote
But to ask again, what's the purpose of using include files for the

interface section of units when most everything in the interface sections remain unchanged among different platforms? Surely we can move all those the parts back to the unit interface sections. Perhaps if you want to match up a single interface declaration with a several include implementations, I can see that as one method of organization, but wouldn't {$region names} in the interface declarations {$endregion} would be an improvement over many interface section include files? This way I can actually scroll through the interface, ctrl+f through the interface, and not be forced to ctrl+enter on interface section includes to see what is being declared.

Looks like you haven't actually looked at how the RTL is structured. It is the way it is for a reason and that is both maintainability and extensibility and yes that also includes the interface. You just need to look at the TJumpBuf record used for setjump()/longjump(), it must be different for each target processor and I honestly don't want that clutter in the interface section, because when you need to work at those parts you'll lose the overview and code folding won't help you then. In short: the RTL will stay as it is, because it's a proven design without better alternatives available.

Regards,
Sven

Reply by email

Anthony Walter
to Sven Barth

For those who didn't understand what I meant by using regions in the interface section rather than include files, here is an image of what is essentially in SysUtils currently:

http://cache.getlazarus.org/images/sysutils-include.gif

Notice the unit file is opened the almost none of what it declares is visible. Instead the declarations are hidden in layers of header include files. This makes it difficult to open a file and see what functions, variables, classes, or types are available and can be used. And I might add that this is problem isn't exclusive to the SysUtils unit.

Now here is an example where the interface section includes are moved to regions:

http://cache.getlazarus.org/images/sysutils-region.gif

Notice you can actually browse through the types and other declarations by simply scrolling down. I understand there might be situations where the interface of a unit might differ per platform, but surely those situations are in the minority, and they could either be placed in {$IFDEF} directives or just those parts could be put in include files. As it is right now nearly everything is is include files and nested include files making browsing source code declarations more difficult than it should be.

It seems like this {$I sysinth.inc} for a header and {$I sysint.inc} for an implementation harkens to C headers and C implementations, something which Pascal is supposed to have done away with.

Reply by email

Michael Van Canneyt
to Anthony Walter
Anthony Walter wrote
For those who didn't understand what I meant by using regions in the interface section rather than include files, here is an image of what is essentially in SysUtils currently:

You are forgetting that not everyone uses Lazarus. The RTL is part of Free Pascal.

For RTL work, I never use lazarus, but a plain old text editor, joe. It doesn't know regions, it doesn't know mainunit etc.

The RTL is organized for the benefit of its maintainers, not the users. It's a proven design since 20 years as explained by Marco and Sven.

The fact that you're the first to complain in 20 years (at least I cannot remember any others, and I've been around for a while) gives you an indication of the relative importance of your problem.

Lazarus IDE shows a tooltip when you hover over an identifier with the mouse. I suspect it will take one on the team less than 10-minutes to add the unit name to the tooltip, in addition to the package and source file name.

Which is, after all, your original problem which is then solved ?

Michael.

Reply by email

Michael Van Canneyt
to Graeme Geldenhuys: As someone that doesn't have access to recent Delphi versions, would you mind sharing a…
Graeme Geldenhuys wrote 12 lines
On 2016-02-10 19:20, Michael Van Canneyt wrote: > You just need to look at the system or sysutils units from recent delphis to > see why include files are the better option, As someone that doesn't have access to recent Delphi versions, would you mind sharing a small example if you can. I'm not at all surprised by your comment though. From the messages I have seen about Delphi these days, not many customers are happy with Delphi's "progress". It sounds like every release is more like a patch-job to get the next set of bullet points filled for the next release. No regard for the language or quality control.

I cannot share code, obviously, but I'll say that the code is a big mess of IFDEFS, used in what seems to me an inconsistent manner (if there is any logic, I fail to see it). Lazarus has understanding of IFDefs, but the Delphi IDE does not (just as it does not understand include files), killing the code navigation, making it hard to navigate or understand these unit.

I normally do not visit these units, so it doesn't harm me, but when I by accident ended up there I remarked it...
I think the problem is more on the poor guys that must maintain it :)

Michael.

Reply by email

Anthony Walter
to Michael Van Canneyt

Michael, a question:

How much of the interface section of units differ per platform? Is it 1% of the code? Is it 5% of the code? With the xml2 unit it's 0%, yet all of the declarations are nested in several layers of include files:

http://cache.getlazarus.org/images/xml2-unit.gif
http://cache.getlazarus.org/images/xml2-include.gif

At what point does putting every interface declaration a {$i includemeh.inc} stop making sense?

Okay, so why do I care? Because I want to be able to read what "stuff" is in a unit by the normal means, and that is to scroll through the declarations of a unit and not be forced to open 40 or more {$i includemeh.inc} files. I want to be able to Ctrl+F in a file and find stuff. I appreciate being able to just read interface declarations to learn/understand what exactly a unit is declaring. Multiple nested includes and no real unit interface declarations is to antithetical most all users ability to learn or understand what is available.

With regards to regions and the RTL, if you for some reason are not using Lazarus they don't hurt anything. Instead they would act like a comment saying "Hey, these declarations are implemented in sysint.inc", which has the same impact as saying {$i sysinth.inc}. The difference is you can actually read the declarations.

And then there is the LCL, which seems to have borrowed the idea of {$i includemeh.inc}. The first declarations of the Controls unit does a {$I controlconsts.inc} and simply lists constant component message identifiers. Why does this need to be an include file? Put it in the Controls unit interface section, and if you want throw a region around it as a comment. You get the added bonus to be able to fold if you're using Lazarus, but if not, hey you get a nice comment.

I have a feeling that if I ran some analytics on the interface section of the RTL I would find > 99.5% of the interface section declarations remain the same across all platforms. I also have the feeling that if an accurate 99.5% analysis was presented here some of you would remain adamant that unit interface declarations should NOT contain actual interface declarations, rather multiple nested include files should contain them.

Reply by email

Sven Barth
to Anthony Walter: For those who didn't understand what I meant by using regions in the interface section…
"Anthony Walter" wrote
For those who didn't understand what I meant by using regions in the

interface section rather than include files, here is an image of what is essentially in SysUtils currently:

http://cache.getlazarus.org/images/sysutils-include.gif Notice the unit file is opened the almost none of what it declares is

visible. Instead the declarations are hidden in layers of header include files. This makes it difficult to open a file and see what functions, variables, classes, or types are available and can be used. And I might add that this is problem isn't exclusive to the SysUtils unit.

Now here is an example where the interface section includes are moved to

regions:

http://cache.getlazarus.org/images/sysutils-region.gif Notice you can actually browse through the types and other declarations

by simply scrolling down. I understand there might be situations where the interface of a unit might differ per platform, but surely those situations are in the minority, and they could either be placed in {$IFDEF} directives or just those parts could be put in include files. As it is right now nearly everything is is include files and nested include files making browsing source code declarations more difficult than it should be.

It seems like this {$I sysinth.inc} for a header and {$I sysint.inc} for

an implementation harkens to C headers and C implementations, something which Pascal is supposed to have done away with.

This won't be changed. Period.
These units are not this way for the sake of browsing, but for the sake of maintainability.

Regards,
Sven

Reply by email

Adriaan van Os
to Michael Van Canneyt: You are forgetting that not everyone uses Lazarus. The RTL is part of Free Pascal. For…
Michael Van Canneyt wrote
he fact that you're the first to complain in 20 years (at least I cannot remember any others, and I've been around for a while) gives you an indication of the relative importance of your problem.

I do share Anthony's (strong) dislike of include files (but I am not complaining about it).

The RTL is organized for the benefit of its maintainers, not the users. It's a proven design since 20 years as explained by Marco and Sven.

The maintainers can choose whatever they like best.

Regards,

Adriaan van Os

Reply by email

Anthony Walter
to Sven Barth: interface section rather than include files, here is an image of what is essentially in…
This won't be changed. Period.

Sven, not to be argumentative, but you do get that for a long time programmers have learned how to write code and use libraries by examining them? My goal is simply to make it easier for the people who would want to pick up and start using Lazarus. Organizing things better for the general developer population, and I'm not just referring to only source code organization, is something I honestly hope this community considers important. I believe that point should be a consideration not just for beginners, but also for the mass of professionals.

Reply by email

Michael Van Canneyt
to Anthony Walter: Michael, a question: How much of the interface section of units differ per platform? Is…
Anthony Walter wrote 5 lines
Michael, a question: How much of the interface section of units differ per platform? Is it 1% of the code? Is it 5% of the code? With the xml2 unit it's 0%, yet all of the declarations are nested in several layers of include files:

Numbers are irrelevant. A particular system is adhered to. It's clearly not your system, but then, one could point out that it's not your code either.

Obviously, I cannot speak for Lazarus' LCL units.

I can only speak for the RTL units.

The files are like this for maintainability:
- Platform dependent parts will always be in separate include files. Forget IFDEF. The few parts where it is used are ugly enough as it is.
- Some interface parts are shared between units: see the unix-specific units as explained by Marco. Sysutils shares e.g. a part with the Strings unit. the DOS unit shares a part with the System unit, if memory serves correctly.
- Smaller files reduce the risk of conflicts when committing changes. While it is common for 2 people to work on sysutils or system, it's already less common that they work on the same functionality.

As said before, these files are organized for the sake of their maintainers. Not the users. What the maintainers deem best, will be used.

Allow me to express some surprise at the vehemence with which you attack this perceived problem.

First, it's not like the identifiers are distributed randomly over arbitrary include files. They are neatly grouped in logical units.

Second, if you want a nice overview of what is implemented in a unit: the documentation is guaranteed to be complete at the time of release, and contains an index per unit and even of all identifiers in the RTL. The sysutils unit documentation contains some topics with 'groups' of functionality. (suggestions always welcome)

In Delphi, that's what I also do if I need an overview; I open the help, and that's it. Only in the very last instance - if I am interested in the actual particulars of an implementation - then I open the source.

And honestly, I cannot even remember when I had to look up something in sysutils or system. I expect experienced people to know these units better than the back of their hand. For beginners I think documentation is better suited.

Michael.

Reply by email

Michael Van Canneyt
to Anthony Walter: Sven, not to be argumentative, but you do get that for a long time programmers have…
Anthony Walter wrote
> This won't be changed. Period. Sven, not to be argumentative,

Funny.
You _are_ argumentative, considering the answers you got and number of posts :-)

(no offense intended)

but you do get that for a long time programmers have learned how to write code and use libraries by examining them?

That may be true for ordinary libraries.

But the RTL is equivalent to Libc.

I suggest you hold a poll for the number of people that learned C (or C++) by studying libc or libstd (or whatever it is called in C++).

I expect you will be disappointed.

Secondly, I don't think the sysutils or system units are a particularly good example. They are a historical image of the attempts (and possible mistakes) of Borland, Inprise, CodeGear, Embarcadero and now Idera, dating back to Turbo Pascal.

Hardly good study material for learning.

My goal is simply to make it easier for the people who would want to pick up and start using Lazarus.

A most noble goal, which I wholeheartedly support !

Therefor I humbly suggest you continue your much-appreciated efforts in writing much more documentation examples and tutorials, improve the documentation engine, help out in getting fppkg and its upcoming web front end deployed.

I think that will help a lot more than us reorganizing the RTL unit files.

Michael.

Reply by email

Michael Van Canneyt
to Mattias Gaertner
Mattias Gaertner wrote 8 lines
> Michael Van Canneyt hat am 11. Februar 2016 um 04:27 > geschrieben: > [...] > Lazarus IDE shows a tooltip when you hover over an identifier with the mouse. > I suspect it will take one on the team less than 10-minutes to add the unit > name to the tooltip, in addition to the package and source file name. Done.

It's a coder... It's a hacker... it's SuperMattias !

Michael.

PS. For those not familiar with the reference:
https://en.wikipedia.org/wiki/It's_a_Bird...It's_a_Plane...It's_Superman

Reply by email

Sven Barth
to Anthony Walter: Sven, not to be argumentative, but you do get that for a long time programmers have…
"Anthony Walter" wrote
> This won't be changed. Period. Sven, not to be argumentative, but you do get that for a long time

programmers have learned how to write code and use libraries by examining them? My goal is simply to make it easier for the people who would want to pick up and start using Lazarus. Organizing things better for the general developer population, and I'm not just referring to only source code organization, is something I honestly hope this community considers important. I believe that point should be a consideration not just for beginners, but also for the mass of professionals.

If they are just learning the language then they shouldn't poke around in the core units anyway. That's what the documentation and help is for. Back when I started learning TP I didn't have the internet and I didn't have the sources of the units. I only had the help and it was definitely enough, so no I'm not even remotely convinced by your argument. Also you aren't someone who's working on that code. New users aren't either. I am. The other maintainers are. *We* need to work in these units, not you. And thus the code is structured in a way that it is suitable for *us* not you.

Regards,
Sven

Reply by email

Unknown author
to Michael Van Canneyt: It's a coder... It's a hacker... it's SuperMattias ! Michael. PS. For those not familiar…
Michael Van Canneyt wrote 11 lines
On Thu, 11 Feb 2016, Mattias Gaertner wrote: >> Michael Van Canneyt hat am 11. Februar 2016 um 04:27 >> geschrieben: >> [...] >> Lazarus IDE shows a tooltip when you hover over an identifier with the mouse. >> I suspect it will take one on the team less than 10-minutes to add the unit >> name to the tooltip, in addition to the package and source file name. > > Done. It's a coder... It's a hacker... it's SuperMattias !

LOL! :thumbsup:

NOTE: No off-list assistance is given without prior approval. *Please keep mailing list traffic on the list* unless private contact is specifically requested and granted.

Reply by email

Mattias Gaertner
to Anthony Walter: Your suggestions only work if a unit declaring the function is in your uses clauses. In…
Show quoted text 6 lines
[...] Additionally, and in a different scenario, when the identifier IS defined and several units are in the uses clause the goto declaration can jump to an include file without any information pertaining to which of the units is including the file. To the best of my knowledge there isn't a straight forward way to figure this out,

If Lazarus has found the declaration there are a few features that might help:

Search / Goto include directive. This will take you one step up.

Code Explorer / Surrounding

Source / Unit Information

Mattias

Reply by email

Jürgen Hestermann
to Sven Barth: programmers have learned how to write code and use libraries by examining them? My goal…
Sven Barth wrote
If they are just learning the language then they shouldn't poke around in the core units anyway. That's what the documentation and help is for. Back when I started learning TP I didn't have the internet and I didn't have the sources of the units. I only had the help and it was definitely enough, so no I'm not even remotely convinced by your argument.

Strange that suddenly the documentation should be used while in the past everybody else is telling me (and others) to look into the code to understand it.

Reply by email

Michael Van Canneyt
to Jürgen Hestermann
Jürgen Hestermann wrote 10 lines
Am 2016-02-11 um 14:21 schrieb Sven Barth: > If they are just learning the language then they shouldn't poke around in the core units anyway. That's what the documentation and help is for. > Back when I started learning TP I didn't have the internet and I didn't have the sources of the units. I only had the help and it was definitely enough, so no I'm not even remotely convinced by your argument. Strange that suddenly the documentation should be used while in the past everybody else is telling me (and others) to look into the code to understand it.

Nothing strange about it.

There is a difference between learning the language, which implies knowing what routines are available to you, and understanding how a particular routine works in detail. The latter requires you to study the source code. For the former, you don't need the details: the documentation is the better alternative.

Michael.

Reply by email

Jürgen Hestermann
to Michael Van Canneyt
Michael Van Canneyt wrote
There is a difference between learning the language, which implies knowing what routines are available to you, and understanding how a particular routine works in detail. The latter requires you to study the source code. For the former, you don't need the details: the documentation is the better alternative.

Here we differ:
I expect that a documentation *fully* explains
a behaviour of a certain function (or something else), not just some part of it.

It's not neccessary to know *how* things are coded but the underlying idea and what the programmer can rely on. The code can even differ from the documenation in case of bugs! So what does it help to look into the code?

If a documenation satisfies the above requirement then
there is no need to look into the code *in any case*.

Reply by email

Andreas Schneider
to Jürgen Hestermann
Jürgen Hestermann wrote
Here we differ: I expect that a documentation *fully* explains a behaviour of a certain function (or something else), not just some part of it.

IMHO that would be insane. To a programmer (like you and me) the RTL and the Compiler are just interfaces. Therefore the documentation describes the contract. I need not and should not need to know the inner workings. All I need to know is the required inputs to get a specific output. The more of the internals you guarantee, the less you can change later on which might even make platform portability impossible.

Look for rarely found details about the JVM. If you do, they are from "hackers", in blogs or the like. Oracle doesn't guarantee you how the interfaces (RTL) are implemented. There are certain constraints every RTL implementation has to fulfill and they are documented. The rest is open to the one implementing it. And in reality there are indeed quite a lot differences. The HotSpot VM works different from JRockit which again works much different from IBMs implementations.

So again - in my opinion - internals are best left out of documentation. Therefore *fully* explaining the behavior would be wrong.

Best regards,
Andreas

Reply by email

Jürgen Hestermann
to Andreas Schneider
Andreas Schneider wrote 7 lines
Am 2016-02-14 12:42, schrieb Jürgen Hestermann: > Here we differ: > I expect that a documentation *fully* explains > a behaviour of a certain function (or something else), > not just some part of it. IMHO that would be insane. To a programmer (like you and me) the RTL and the Compiler are just interfaces. Therefore the documentation describes the contract. I need not and should not need to know the inner workings. All I need to know is the required inputs to get a specific output. The more of the internals you guarantee, the less you can change later on which might even make platform portability impossible.

Fully agree, exactly what I was trying to say.

So again - in my opinion - internals are best left out of documentation. Therefore *fully* explaining the behavior would be wrong.

I would differentiate between "details" and "internals". Of course, the exact coding ("internals") should not be part of the documentation. But the "details" - which I would name the behaviour under all (even rare) circumstances - should be fully documented. There should be no doubt what I can expect and what not.

But in this forum very often when someone complains about missing or incomplete documentation he gets the advice to look into the code which IMO is insane because

1.) the code may change over time
2.) it can have bugs (which I would rely on)
3.) it is often hard to understand if I don't know about the surrounding concepts and other things.

Also, the documentation is very important for the programmer as it lets him think about what he is coding (and only the programmer knows what he had in mind when he coded something). I often found that my code was imcomplete or otherwise misconcepted as I tried to explain it to someone else.

Reply by email