Recent

Author Topic: uses in implementation?  (Read 10030 times)

darksky

  • New Member
  • *
  • Posts: 15
uses in implementation?
« on: December 22, 2014, 01:00:13 pm »
1. Do you know of 'uses' being used in interface as well as implementation section of a unit?

I think I have seen it being used to in both interface and implementation section of a unit (I don't remember where though >:( ). Why would you want to do that?

2. And I have no idea which units I should be including and when -- I mean when should I include classes unit for example, and how am I supposed to know which unit to include and for what?

Thanks..
« Last Edit: December 22, 2014, 01:01:54 pm by darksky »

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: uses in implementation?
« Reply #1 on: December 22, 2014, 01:15:27 pm »
The implementation uses section is used mainly to avoid circular reference, but also for local use files.

You need to study Lazarus units and memorize in which units are which classes. Or you can use a feature in Lazarus to find Identifiers with the mouse right button (right-click on the compiler message "Identifier not found"and choose "Find Identifier").
« Last Edit: December 22, 2014, 01:19:50 pm by typo »

Ocye

  • Hero Member
  • *****
  • Posts: 518
    • Scrabble3D
Re: uses in implementation?
« Reply #2 on: December 22, 2014, 01:20:00 pm »
I think I have seen it being used to in both interface and implementation section of a unit... Why would you want to do that?
A reason could be to bypass circular references (which is supposed to be bad design). And I guess there are more reasonable aspects of visibility that makes sense to use units in the interface part only.
Which unit you need is basically done by Lazarus. That means if you drop an object onto the form designer the appropriate unit is added automatically. In case you do not work with an IDE you have to know, though. A good starting point would be the wiki. For example, classes is documented here http://lazarus-ccr.sourceforge.net/docs/rtl/classes/index.html
Lazarus 1.7 (SVN) FPC 3.0.0

Ñuño_Martínez

  • Hero Member
  • *****
  • Posts: 1186
    • Burdjia
Re: uses in implementation?
« Reply #3 on: December 22, 2014, 02:04:49 pm »
1. Do you know of 'uses' being used in interface as well as implementation section of a unit?

I think I have seen it being used to in both interface and implementation section of a unit (I don't remember where though >:( ). Why would you want to do that?
RTFM

INTERFACE is the public declarations of your UNIT.  IMPLEMENTATION is the implementation of the public declarations (hence it's private for each UNIT).

So, USES section in the INTERFACE declares which units are needed by public declarations, and USES section in the IMPLEMENTATION declares which units are needed by the unit implementation.

2. And I have no idea which units I should be including and when -- I mean when should I include classes unit for example, and how am I supposed to know which unit to include and for what?.
Again RTFM.  Documentation includes the UNIT you need to add in each case.
« Last Edit: December 22, 2014, 02:11:50 pm by Ñuño_Martínez »
Are you interested in game programming? Join the Pascal Game Development community!
Also visit the Game Development Portal

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11446
  • FPC developer.
Re: uses in implementation?
« Reply #4 on: December 22, 2014, 02:16:10 pm »
The main reason is indeed circular references.  All interfaces of uses'd units must be compiled before the current unit can be compiled (since those are the contracts to use those other units). And all the interfaces of the units they use in the interface too etc etc. 

Implementation uses on the other hand are only checked when actually compiling the body of that unit.

There are some complications like cross-unit inline, and a simple system that tries to resolve very simple cases of mutual recursion (A uses B and vice versa while no types are used recursively in the interface)

Being so strict has some advantages for quality of error generation and avoiding occasional errors. Which are a good thing for a language aimed at large programs.

darksky

  • New Member
  • *
  • Posts: 15
Re: uses in implementation?
« Reply #5 on: December 23, 2014, 08:20:06 am »
Okay thank you guys, if i remember correctly, i was reading some Delphi code, which is where i think i saw uses in both implementation and interface. Anyway, so it's up to the programme to avoid bad coding.. if i understood it correctly, else it'd be fine to declare it only in the interface right?

Leledumbo

  • Hero Member
  • *****
  • Posts: 8757
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: uses in implementation?
« Reply #6 on: December 23, 2014, 08:26:18 am »
Anyway, so it's up to the programme to avoid bad coding.. if i understood it correctly, else it'd be fine to declare it only in the interface right?
Yes. My personal guide is to put in in the right place. If the interface doesn't require anything from the unit but the implementation does, then declare the respective unit in the implementation's uses section. Otherwise, put it in interface's uses.

darksky

  • New Member
  • *
  • Posts: 15
Re: uses in implementation?
« Reply #7 on: December 23, 2014, 08:38:08 am »
Thank you @Leledumbo.
« Last Edit: December 23, 2014, 08:49:10 am by darksky »

darksky

  • New Member
  • *
  • Posts: 15
Re: uses in implementation?
« Reply #8 on: December 23, 2014, 11:25:22 am »
and also, how do you get GUID when you're making an interface? can I just insert random numbers?

Leledumbo

  • Hero Member
  • *****
  • Posts: 8757
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: uses in implementation?
« Reply #9 on: December 23, 2014, 11:30:50 am »
and also, how do you get GUID when you're making an interface? can I just insert random numbers?
Yes, or SysUtils.CreateGUID

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: uses in implementation?
« Reply #10 on: December 23, 2014, 11:35:18 am »
In the Lazarus IDE you can use the shortcut (the default is set to Shift-Ctrl-G) to the main menu item
Source->Insert General->Insert a GUID

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4467
  • I like bugs.
Re: uses in implementation?
« Reply #11 on: December 23, 2014, 03:01:08 pm »
Yes. My personal guide is to put in in the right place. If the interface doesn't require anything from the unit but the implementation does, then declare the respective unit in the implementation's uses section. Otherwise, put it in interface's uses.

That is a good strategy. Another good strategy is to put everything into interface section unless it creates a circular reference. Then a reference from implementation section works also as an indicator of a circular reference which is always a "serious" thing design-wise.
I have only in recent years realized the importance of managing and restricting dependencies. When you look at design patterns, there are boxes and arrows between them and the arrow always points to one direction only, meaning the reference is in one direction. There are never circular references in design patterns! In fact the fundamental idea of most patterns is to reduce dependencies and thus make the code more modular and easier to maintain and reuse.
This is more or less agreed by everybody when discussing about design patterns. However I have not seen any discussion about how programming languages support those design ideas. Do they try to enforce a one-way dependency? No, almost all languages allow circular references happily without warnings. Object Pascal + some Pascal related languages may be the only ones that try to guide programmers by banning circular references between interfaces completely.

Lazarus code tries to avoid any circular reference including the legal one through implementaion section. FPC used to have a bug when there were many such dependencies and some developers claimed it is the reason for limiting any circles. Later I realized it was more an excuse. Removing dependencies improves the code quality almost always. It works like a filter through which you press the code and it becomes good.
I have changed my opinion on this matter completely. Only at 2009, less than 6 years ago, I wrote how the circular reference restriction in Object Pascal is a PITA and prevents it becoming more popular. Since then I have studied the topic of why code-rot happens and why big projects often become near-impossible to maintain.
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

Leledumbo

  • Hero Member
  • *****
  • Posts: 8757
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: uses in implementation?
« Reply #12 on: December 24, 2014, 04:52:02 am »
Do they try to enforce a one-way dependency? No, almost all languages allow circular references happily without warnings.
Indeed:
  • Haskell requires additional info to tell the compiler, which one is the source module
  • Ruby mutual require results in NameError
  • Lua will end in "loop or previous error loading module xxx". (Ugly) workaround exists, though.
  • Python can only do it for full import, partial import (using from) will fail. At the 2nd import of previously imported module, it simply resumes from the point where it's left. This is due to Python being interpreted and import is just another statement that the interpreter can execute.
  • Nimrod follows Python, with exception is that you can only use symbols which are already parsed at the time import statement is encountered
  • Java doesn't import modules, only classes
  • C/C++ requires manual intervention using include guard. Practically, C/C++ don't really have proper module support
In theory, it should be possible for Object Pascal to do the same, or at least provides hack/workarounds. But isn't the language designed to safe you from shooting yourself in the foot? It's proven from languages above's manual or QA how circular dependency is a complex case to handle with complex rules to obey, and their implementation maintainers almost always suggest to avoid it ;)

darksky

  • New Member
  • *
  • Posts: 15
Re: uses in implementation?
« Reply #13 on: December 24, 2014, 08:06:09 am »
Thank you Leledumbo and howardpc..
« Last Edit: December 24, 2014, 08:08:19 am by darksky »

MathMan

  • Sr. Member
  • ****
  • Posts: 325
Re: uses in implementation?
« Reply #14 on: December 24, 2014, 10:48:29 am »
Do they try to enforce a one-way dependency? No, almost all languages allow circular references happily without warnings.
Indeed:
  • Haskell requires additional info to tell the compiler, which one is the source module
  • Ruby mutual require results in NameError
  • Lua will end in "loop or previous error loading module xxx". (Ugly) workaround exists, though.
  • Python can only do it for full import, partial import (using from) will fail. At the 2nd import of previously imported module, it simply resumes from the point where it's left. This is due to Python being interpreted and import is just another statement that the interpreter can execute.
  • Nimrod follows Python, with exception is that you can only use symbols which are already parsed at the time import statement is encountered
  • Java doesn't import modules, only classes
  • C/C++ requires manual intervention using include guard. Practically, C/C++ don't really have proper module support
In theory, it should be possible for Object Pascal to do the same, or at least provides hack/workarounds. But isn't the language designed to safe you from shooting yourself in the foot? It's proven from languages above's manual or QA how circular dependency is a complex case to handle with complex rules to obey, and their implementation maintainers almost always suggest to avoid it ;)

From a theoretical perspective circular dependencies can be avoided completely - just put everything in one unit  ;) But for good reason modularization of programms is often the way to go and then there is a simple conflict between design and actual implementation. I'd rather prefer a language that tells me about it - making me aware that this conflict exists - and let me handle it, then silently accepting crude designs!

I try to think of it as an analogon of forward references. One can do completely without it (if typecast is avail. in your language of choice) at the expense of readability and maintainability of the source code.

Cheers,
MathMan

 

TinyPortal © 2005-2018