Jump to content
RCrandall

What is the benefit of sorting the Uses clause?

Recommended Posts

I am returning to MMX after a long break and I'm exploring it all again.  I dimly recall seeing that the order of the Uses clauses can affect compilation speed, a problem I'm having, but I'm far from sure of that.  Is this the benefit of formatting the list of used units?  Or is to improve readability, or some other reason?

 

Inquiring minds want to know, thanks, Rob C

Share this post


Link to post

It started with the request to expand the unit scope names, which gave a good boost to compile time in some cases. The idea of uses clause grouping and sorting crept in my mind when I noticed difficulties to quickly scan the list of used units. With a sorted and grouped uses clause the used libraries are clearly visible immediately. So its partly for compilation speed as well as a neat look (some call it OCD).

  • Like 2

Share this post


Link to post

Sorting units by name is dangerous.

There are some units that need to be added at the end of the list, if they overwrite some behavior's of objects and functions of other units above in the list. There are other units that need to be placed on top of the list if they do some special initialization that needs to be done in the app as soon as possible, before any other parts of the app start to initialize.

  • Like 4

Share this post


Link to post
43 minutes ago, Fred Ahrens said:

Sorting units by name is dangerous.

Albeit there actually is a request for that, MMX does not sort the units by name. They are grouped according to a user defined pattern, but inside the group the order stays intact.

 

F.i. this is the Groups entry for one of my projects: 

image.thumb.png.bc83a5936ca041b7c68e0d2eb42a4934.png

 

After some Delphi units in a decent order based on dependency, there are the Raize and TMS units followed by VirtualTreesPngComponents and the ZipForge units. The last four mimic the unit scopes and naming convention of the project itself also ordered by dependency.

(TMS can improve their unit naming btw.)

 

A typical uses clause looks like this:

uses
  Winapi.Messages,
  System.Classes, System.Actions, System.Types, System.ImageList,
  Vcl.Graphics, Vcl.Menus, Vcl.ActnList, Vcl.Controls, Vcl.ExtCtrls, Vcl.Forms, Vcl.StdCtrls, Vcl.Tabs, Vcl.Dialogs, Vcl.ImgList,
  Vcl.VirtualImageList, Vcl.AppEvnts,
  RzTabs, RzForms, RzShellDialogs, RzPanel, RzButton, RzSplit, RzCommon,
  Common.Form,
  IpButton, IpMRU, IpMultiLanguageSupport,
  TcEditorTypes, TcGlbCfgSystem, TcGlbCfgVisualStyle,
  RNcCodeViewer, REditorStructure, REditorItems, RBasePalette, RStoragePalette, REditorPalette, RCustomPalette, REditorPanel,
  RBaseFrame, RObserver, RStandardStatus, REditorNesting, RBaseEditorFrame;

 

The grouping algorithm is pretty flexible and I never had a case that could not be handled.

 

If auto-sort a uses clause is automatically sorted whenever MMX modifies it - a very handy feature.

  • Like 1

Share this post


Link to post
2 hours ago, Fred Ahrens said:

Sorting units by name is dangerous.

There are some units that need to be added at the end of the list, if they overwrite some behavior's of objects and functions of other units above in the list. There are other units that need to be placed on top of the list if they do some special initialization that needs to be done in the app as soon as possible, before any other parts of the app start to initialize.

Actually this means there is a design flaw (i know, hard to not have this situations, we have them also, but in reallity it's something to fix i think).

How you going explain 15years later that unit xyz has to be before unit abc, put some text in comments ?

 

  • Like 1

Share this post


Link to post
9 hours ago, Fred Ahrens said:

Sorting units by name is dangerous.

There are some units that need to be added at the end of the list, if they overwrite some behavior's of objects and functions of other units above in the list. There are other units that need to be placed on top of the list if they do some special initialization that needs to be done in the app as soon as possible, before any other parts of the app start to initialize.

Although the real problem is the language design that makes this order affect the meaning of the program. 

  • Like 2

Share this post


Link to post

I remember having this discussion with an american on LinkedIn. He had written a tool that sorted the uses clause, and he turned a darker shade of crazy when I pointed out the risks, "chanting" USA, USA, USA. No point in discussing with such people.

  • Haha 3

Share this post


Link to post
18 hours ago, Uwe Raabe said:

It started with the request to expand the unit scope names, which gave a good boost to compile time in some cases. The idea of uses clause grouping and sorting crept in my mind when I noticed difficulties to quickly scan the list of used units. With a sorted and grouped uses clause the used libraries are clearly visible immediately. So its partly for compilation speed as well as a neat look (some call it OCD).

"Expand unit scope names" - that was it. Thanks for the speedy reply and I appreciate all the other comments too.

 

Rob C

Share this post


Link to post
9 hours ago, Lars Fosdal said:

... "chanting" USA, USA, USA. No point in discussing with such people.

Probably you misunderstood him a little, since this was his desired (world) sort order ... 🤔

  • Haha 1

Share this post


Link to post
On 9/1/2023 at 2:39 AM, mvanrijnen said:

Actually this means there is a design flaw

RTL itself suffers from this flaw for some identifiers (mostly WinAPI / generic types clash). Luckily these issues are detected by compiler but could cause serious issues if these types are used as untyped pointers

 

Share this post


Link to post
On 8/31/2023 at 5:00 PM, Uwe Raabe said:

image.thumb.png.bc83a5936ca041b7c68e0d2eb42a4934.png

How do you configure groups like (ZipForge)? I could not find that in MMX Properties or MMX Project Options.

 

I would like to do this for ImageEn and maybe others. ImageEn units do not have a consistent prefix suitable for grouping.

 

Thanks!

 

Thanks

Share this post


Link to post

Brackets denote a list of unit names forming a group. I use it f.i. for keeping the ToolsApi units together: (ToolsApi,DesignIntf,DCCStrs,DockForm,TabDock)

 

The example shows a glitch in the TMS unit naming: Adv* followed by (BaseGrid) keeps the TMS Grids unit together.

 

The other example (ZipForge) is used when a group consists of a single unit name only. Omitting the brackets would take it as a unit scope name instead.

 

 

  • Thanks 1

Share this post


Link to post

Uwe,

 

where do I find this groups dialog? Is this a new feature you are working on?  

Found it!

 

Thanks!

 

Edited by ULIK

Share this post


Link to post

@Uwe Raabe

Hi...😎

 

Is it possible to start each group in a new line?

uses
  Winapi.Windows,
  System.Classes, System.Generics.Collections, System.Generics.Defaults, System.SysUtils,
  ...

 

Share this post


Link to post
26 minutes ago, haentschman said:

Is it possible to start each group in a new line?

That's default.

Share this post


Link to post

...🤔

before:

uses
  System.Classes, System.SysUtils, System.Variants, System.Generics.Collections, System.Generics.Defaults, System.DateUtils, System.Math, System.StrUtils,
  Vcl.Imaging.pngimage,
  Data.DB,
  FireDAC.Stan.Param, FireDAC.Stan.Option, FireDAC.Comp.Client, FireDAC.Comp.Script,
  DataModuleTextConstants,
  x.Classes.Common, x.Classes.Base, x.Classes.Data, x.Constants, x.Types,
  x.Tools.Mapping, x.Tools.DateTime, x.Tools.TryFinally, x.Tools.Json, x.Tools.Regex, x.Tools.IO, x.Tools.BitMask,
  x.Database.Common,
  x.Preferences;

after:

uses
  System.Classes, System.SysUtils, System.Variants, System.Generics.Collections, System.Generics.Defaults, System.DateUtils, System.Math,
  System.StrUtils, Vcl.Imaging.pngimage, Data.DB, FireDAC.Stan.Param, FireDAC.Stan.Option, FireDAC.Comp.Client, FireDAC.Comp.Script,
  DataModuleTextConstants, x.Classes.Common, x.Classes.Base, x.Classes.Data, x.Constants, x.Types, x.Tools.Mapping,
  x.Tools.DateTime, x.Tools.TryFinally, x.Tools.Json, x.Tools.Regex, x.Tools.IO, x.Tools.BitMask, x.Database.Common,
  x.Preferences;

image.thumb.png.f01a121d72a14d0b50181b643a08e482.png

Share this post


Link to post

Sorry...😉

PS: with "*" ("Form.*") also...  

PS: FireDAC and more are missing (first test)  😉

image.png.272c0bbfe4a7a6aec91ac0ff1fc7e9b9.png

 

Edited by haentschman

Share this post


Link to post

I have: Winapi;System.Win;System;Data;Vcl;obsidium;Adv*;(BaseGrid);Virtual*;FireDAC;REST;Xml;fcx*;VclTee;jst*;Vst*;sub*;u*

Result:

uses
  Winapi.Windows, Winapi.Messages,
  System.SysUtils, System.Variants, System.Classes, System.Generics.Collections, System.Generics.Defaults,
  System.DateUtils,
  Data.DB,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls,
  advofficepager, AdvMemo, advglowbutton, advpanel, advstyleif, advappstyler,
  FireDAC.Comp.Client, FireDAC.Stan.Param,
  jstAdvPanel,
  BasalForm, Htmlabel;

Share this post


Link to post

Better remove the trailing dots in Frame and Form. Plain group names get that automatically appended when looking for a match.

 

F.i. a simple entry like Form matches unit names Form, Form.Tools and Form.Test, but not FormTest.

 

Assuming that the x stands for the obfuscated parts in your screenshot, I get the following results with this Groups: 

Winapi
System.Win
System
Vcl
Data
FireDAC
cx
DM
x
x.Tools
Frame
Form
uses
  System.Classes, System.SysUtils, System.Variants, System.Generics.Collections, System.Generics.Defaults, System.DateUtils,
  System.Math, System.StrUtils,
  Vcl.Imaging.pngimage,
  Data.DB,
  FireDAC.Stan.Param, FireDAC.Stan.Option, FireDAC.Comp.Client, FireDAC.Comp.Script,
  x.Classes.Common, x.Classes.Base, x.Classes.Data, x.Constants, x.Types, x.Database.Common, x.Preferences,
  x.Tools.Mapping, x.Tools.DateTime, x.Tools.TryFinally, x.Tools.Json, x.Tools.Regex, x.Tools.IO, x.Tools.BitMask,
  DataModuleTextConstants;

 

Share this post


Link to post
11 minutes ago, Attila Kovacs said:

Each unit name belongs to a new line, with groups separated by an empty line.

As that is a very personal preference, a similar feature is implemented on personal request in UsesCleaner branch FlixEngineering. It is available in the public repository for all those having individual formatting requests.

 

Note that MMX will most likely not contain these for the near future.

Share this post


Link to post
3 hours ago, Attila Kovacs said:

Each unit name belongs to a new line, with groups separated by an empty line.

Actually, instead of an empty line, it could be a comment with the group, e.g.

uses
  // Windows group
  Windows.WinApi
  // vcl group
  vcl.bla,
  vcl.blub;

So it doesn't look like somebody forgot to remove an empty line.

Edited by dummzeuch
  • Like 1

Share this post


Link to post

😢 I put this in the groups...

Quote

Winapi
System.Win
System
Vcl
Data
FireDAC
cx
DM
x
x.Tools
Frame
Form

 

after:

uses
  System.Classes, System.SysUtils, System.Variants, System.Generics.Collections, System.Generics.Defaults, System.DateUtils, System.Math,
  System.StrUtils, Vcl.Imaging.pngimage, Data.DB, FireDAC.Stan.Param, FireDAC.Stan.Option, FireDAC.Comp.Client, FireDAC.Comp.Script,
  DataModuleTextConstants, x.Classes.Common, x.Classes.Base, x.Classes.Data, x.Constants, x.Types, x.Tools.Mapping,
  x.Tools.DateTime, x.Tools.TryFinally, x.Tools.Json, x.Tools.Regex, x.Tools.IO, x.Tools.BitMask, x.Database.Common,
  x.Preferences;

What ist wrong?

PS: 15.1.8

Edited by haentschman

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×