Lazarus

Miscellaneous => Other => Topic started by: Ñuño_Martínez on June 04, 2021, 12:08:59 pm

Title: [opinion][Research] API design
Post by: Ñuño_Martínez on June 04, 2021, 12:08:59 pm
So, I’m rewriting my engine and I’m struggling with API names.

I was using prefixes and suffixes to differentiate the engine and subsystems stuff.  For example, this program for an hypothetical action game:
Code: Pascal  [Select][+][-]
  1. program Game;
  2.  
  3.   uses
  4.     Mingro, mngSprites, Title, Playfield, sysutils;
  5.  
  6.   function Initialize: Boolean;
  7.   begin
  8.     if mngInit and mngInitializeSprites then
  9.     begin
  10.       if mngLoadSpriteSheet ('player.spr') then
  11.         Exit (True)
  12.       else begin
  13.         mngLog.Trace (etError, 'Can''t load sprite sheet.');
  14.         Exit (False)
  15.       end
  16.     end
  17.     else begin
  18.       mngLog.Trace (etError, 'Can''t init engine!');
  19.       Exit (False)
  20.     end
  21.   end;
  22.  
  23. begin
  24.   if Initialize then while RunTitle do RunGame
  25. end.

What I was thinking is to use the unit name as namespace, so the previous program will look like this:

Code: Pascal  [Select][+][-]
  1. program Game;
  2.  
  3.   uses
  4.     Mingro, mngSprites, Title, Playfield, sysutils;
  5.  
  6.   function Initialize: Boolean;
  7.   begin
  8.     if Mingro.Initialize and mngSprites.Initialize then
  9.       if mngSprites.LoadSheet ('player.spr') then
  10.         Exit (True)
  11.       else begin
  12.         Mingro.Log.Trace (etError, 'Can''t load sprite sheet.');
  13.         Exit (False)
  14.       end
  15.     else begin
  16.       Mingro.Log.Trace (etError, 'Can''t init engine!');
  17.       Exit (False)
  18.     end
  19.   end;
  20.  
  21. begin
  22.   if Initialize then while Title.Run do Playfield.Run
  23. end.

I don’t see that kind of API anywhere but I think it is clean and clear and more appealing than using prefix/sufix to differentiate between subsystems (except the fact that when two units declare an object with same name and you don’t precede it with the unit name, FPC doesn’t warns and picks one resulting in some funny debug sessions).

What do you think about this kind of API?
Title: Re: [opinion][Research] API design
Post by: denis.totoliciu on June 04, 2021, 12:19:23 pm
It is an interesting point of view and I think it works pretty when you have units that use short names along with structured programming. There are some down factors to using this way of writing source code, but if you keep it simple, it can work well for smaller projects.

This style of writing code is similar to using classes.
Title: Re: [opinion][Research] API design
Post by: MarkMLl on June 04, 2021, 12:29:19 pm
This style of writing code is similar to using classes.

In practical terms, the syntax is just about identical whether e.g. mngLog is a unit or is a class. I use that to swap seamlessly between static and dynamic linkage, and have a mostly-completed tool which handles most of the unit-generation work.

MarkMLl
Title: Re: [opinion][Research] API design
Post by: 440bx on June 04, 2021, 12:30:26 pm
(except the fact that when two units declare an object with same name and you don’t precede it with the unit name, FPC doesn’t warns and picks one resulting in some funny debug sessions).

What do you think about this kind of API?
I think you hit the nail on the head about using the unit name.  As you mentioned, if two units declare a function/procedure with the same name, that can create some difficult to find bugs.

Prefixes have a big advantage: unlike unit names, they are not optional and if forgotten, the compiler will usually complain about an unknown identifier.  That makes it much more unlikely to have two different (but unfortunately similar) routines with the same names in different units.

Using prefixes is more robust.



Title: Re: [opinion][Research] API design
Post by: Ñuño_Martínez on June 04, 2021, 12:52:20 pm
So one yes and one not (just kidding).

The compiler warning issue is what concerns me more, but I still like the idea of using unit names as namespaces...
Title: Re: [opinion][Research] API design
Post by: munair on June 04, 2021, 12:57:50 pm
If I'm not mistaken the pascal compiler takes the first unit it comes across that holds the referred procedure. If the programmer refers to the same procedure from another unit, the unit must be used as prefix. In small projects this may seem trivial, but even then conflicts with libraries can result in unexpected compiler complaints or even unexpected outcomes.
Title: Re: [opinion][Research] API design
Post by: 440bx on June 04, 2021, 12:59:54 pm
Wouldn't using the unit name create a hindrance with Codetools ? ..  it seems like it would get in the way of codetools being really helpful since it will display everything that is visible in the unit every time the unit name is typed (i.e, too many choices, loss of practicality.)



Title: Re: [opinion][Research] API design
Post by: Ñuño_Martínez on June 05, 2021, 11:46:09 am
If I'm not mistaken the pascal compiler takes the first unit it comes across that holds the referred procedure. If the programmer refers to the same procedure from another unit, the unit must be used as prefix. In small projects this may seem trivial, but even then conflicts with libraries can result in unexpected compiler complaints or even unexpected outcomes.
Yep, I know.  That's just why I'm asking for opinion.  Also I think people isn't aware of modern Pascal's moduleness.  I always find it awesome and underrated,  and I don't understand why to add namespaces: units are namespaces by their own!

Wouldn't using the unit name create a hindrance with Codetools ? ..  it seems like it would get in the way of codetools being really helpful since it will display everything that is visible in the unit every time the unit name is typed (i.e, too many choices, loss of practicality.)
I mostly use Vim so... ::)
Title: Re: [opinion][Research] API design
Post by: lucamar on June 05, 2021, 04:59:29 pm
[...] I don't understand why to add namespaces: units are namespaces by their own!

Namespaces are meant to take that concept (SomeUnit.SomeProc) one step above and be able to use same-named units (say, from two different packages) and resolve which is used. Say, for example, when you want to have a globals or a StrConst unit; it's to difficult to find a more expressive or appropiate name for those, but it's fine if you can refer to: MyVeryOwnPackage.Globals ;)
Title: Re: [opinion][Research] API design
Post by: Ñuño_Martínez on June 05, 2021, 07:59:23 pm
I didn't know that about namespaces. I thought it was just add a new level. Interesting.
TinyPortal © 2005-2018