-
Content Count
1111 -
Joined
-
Last visited
-
Days Won
96
Everything posted by Dalija Prasnikar
-
Recursive anonymous functions
Dalija Prasnikar replied to Primož Gabrijelčič's topic in Algorithms, Data Structures and Class Design
var [weak] fib: TFunc<integer,int64>; Marking it as weak breaks the cycle. However, there was a bug with weak that is only recently fixed (not sure whether in 10.3 or 10.3.1) -
10.3.1 has been released
Dalija Prasnikar replied to Martin Sedgewick's topic in Delphi IDE and APIs
Error Insight has always been Error Inside. It never worked properly, and was always lagging behind. -
What is meant as 'implementation detail' vs 'non-implementation detail'?
Dalija Prasnikar replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
If only making good examples would be so simple.... it is so much easier to trash other people's examples... Joking aside... bad examples (or ambiguous examples) can make more damage than good. OOP is complex matter and not always straightforward. Ask 100 experts about it and you will get 100 different answers. My rule of thumb is learn about OOP, design patterns, testing and then apply common sense over it. If some rules collide, then apply KISS (Keep it simple, stupid) and YAGNI (You aren't gonna need it) and DRY (Don't repeat yourself) before any other principles. If it seems too convoluted or you don't have clear understanding why... better don't use it than use it in a wrong way. That does not mean people should not strive to learning and understanding better practices. In that context, primary goal of encapsulation is protecting implementation details that can change to avoid subsequent changes in consumer code. When you write your own classes you are the boss, you can decide what is implementation detail and what is not. Of course, you have to be careful about those decisions because you will have to live with them for a long time. When you consume other people's classes you must avoid using things that are not part of public API. Since it is not always possible to hide all implementation details, it is possible that not everything that is publicly accessible is really part of documented public API. Unless public API is clearly documented, sometimes it can be hard to know what is implementation detail, and what is not. Experience can help, but it is hard to give any good general tips on the matter - it all depends on the actual code. And this is where original question came from - what is implementation detail in some code and why is better to use some construct comparing to another. Another thing to keep in mind is that OOP depend on the language. What fits in one, does not fit well in another. In Java encapsulation means having geter and setter methods for everything accessible - because Java does not have properties. If you expose field directly any changes in access logic that has to go through geter or setter will require changes in consumer code - because Java expects parens () when you access method. In Delphi you might as well start with directly exposed field... changing that into property will not change consumer code (unless you add read or write restrictions) and adding geter or setter methods will also have no direct impact on consumer code. Of course, most Delphi developers will use properties instead of directly exposing fields, but this is more of common practice than actual requirement for fields that will be publicly accessible - part of the public API. I could probably go on for days... but I have other things to do... 🙂 -
What is meant as 'implementation detail' vs 'non-implementation detail'?
Dalija Prasnikar replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Sorry, but you started going off rails saying that you should not use fabc.ToString for displaying integer value as text, thus blowing the whole encapsulation and hiding the implementation thing out of proportion. Now, it is possible that you just used poor example and that you actually tried to say something completely different. I am not trying to shred concepts to pieces, I am just trying to show their usage must be balanced. Abusing the concepts to the point of absurdity is as bad as not using them at all. What better example to show how not everything can be absolutely hidden and protected than to show that strings itself are leaking their implementation details. -
What is meant as 'implementation detail' vs 'non-implementation detail'?
Dalija Prasnikar replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
I found something... not mine.... actually, the original thoughts on leaky abstractions https://www.joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions/ -
What is meant as 'implementation detail' vs 'non-implementation detail'?
Dalija Prasnikar replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
No. It was not about leaking strings, rather Delphi strings leaking their implementation details like character size, encoding... Think about going from TP fixed size string implementation to pre-Unicode Delphi string implementation to Unicode Delphi string implementation. I remember writing about it, but don't remember where... -
What is meant as 'implementation detail' vs 'non-implementation detail'?
Dalija Prasnikar replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
I cannot find it either... I don't think it was a blog post... maybe some post on G+ or somewhere else... -
What is meant as 'implementation detail' vs 'non-implementation detail'?
Dalija Prasnikar replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Not all of it. It only hides the integer, but it does not hide how you implemented conversion from integer to string. Also, string type itself leaks its implementation details in Delphi all over the place. You are going extra mile to hide just about everything - without real reasons. Point is, no matter how far you go, you can never hide all implementation details. In one way or another they will leak. It is perfectly acceptable to have integer function or property as part of well defined public API. The whole point of hiding implementation details, and not using them is that by doing so, you can change implementation without changing the public interface and without need to change all the code that relies upon it. That is the purpose of having well defined public API. Hiding inner collection implementation (so you can easily replace plain array with list or some other structure) or some other more complex data is one thing, but hiding basic type like integer is going over the top without actually accomplishing anything. One of the problems when it comes to following good practices like testing, proper OOP design... is that quite often those practices are explained and taught by going into extremes, making them overly complicated and losing original intent - making better, more maintainable code, with less bugs. That blowing things out of proportion, not only makes it harder to understand basic principles behind those practices but it also makes many developers just to drop the whole thing and not use any. It is hard to blame them when they see no point. -
Solution(s) for coder with quite poor eyesight
Dalija Prasnikar replied to Tommi Prami's topic in Delphi IDE and APIs
Pretty good, but not ideal. -
Solution(s) for coder with quite poor eyesight
Dalija Prasnikar replied to Tommi Prami's topic in Delphi IDE and APIs
There is plenty... HP, Dell, ViewSonic... it should not be hard to find suitable one. I am using 1920x1080 at 24" and I have seen 27" 2K monitor simulating HD resolution using 100% font sizes. I could read it across the room. -
Solution(s) for coder with quite poor eyesight
Dalija Prasnikar replied to Tommi Prami's topic in Delphi IDE and APIs
27" monitor with 1920x... resolution and 100% font size might be good enough. There is quite a difference between 24" and 27". -
10.3.1 has been released
Dalija Prasnikar replied to Martin Sedgewick's topic in Delphi IDE and APIs
Something is not right with your installation. Mine shows 10.3 update 1 -
10.3.1 has been released
Dalija Prasnikar replied to Martin Sedgewick's topic in Delphi IDE and APIs
IDE no longer flickers when you compile/build 😃 Probably the most important fixes and improvements are in iOS platform - including fix for compiling/linking 3rd party libraries against iOS 12 SDK. And then there is a bunch of bug fixes in other areas. So plenty of improvements, just not big ones. Or depends how you look at it, if your code was affected, then even single small fix can be great improvement. -
Pitfalls of Anonymous methods and capture
Dalija Prasnikar replied to Lars Fosdal's topic in RTL and Delphi Object Pascal
or MCVE Minimal, Complete, and Verifiable Example -
Pitfalls of Anonymous methods and capture
Dalija Prasnikar replied to Lars Fosdal's topic in RTL and Delphi Object Pascal
To be honest, knowing the type of Handler.OnHandle is crucial for understanding the issue. The other implementation details don't matter as much. Broker.AddHandler(Handler.OnHandle); And usually I don't go around and download code examples, just to get to the bottom of some problem. Only under special circumstances - mostly from bugs reported in QP, when having complete test project is crucial for reproducing the issue. The only reason, why I did go and download this example is because I know you. So whether you like it or not, David does have a point. -
Pitfalls of Anonymous methods and capture
Dalija Prasnikar replied to Lars Fosdal's topic in RTL and Delphi Object Pascal
You are on right track. What happens is something like this: procedure TTest.ConfigLoop; var Handler: THandlerClass; hType: THandlers; hRef: TOnHandle; begin Writeln; Writeln('--- ConfigLoop'); Broker.Clear; for hType in [foo, bar] do begin case hType of foo: Handler := TFoo.Create; bar: Handler := TBar.Create; // wtf: ; end; hRef := Handler.OnHandle; // Capture does no discern between the foo instance and the bar instance Broker.AddHandler(hRef); end; end; and then this bridging assignment from plain method to anonymous method is expanded to hRef := procedure begin Handler.OnHandle(); end; Where before mentioned rules about capturing references (variables) and not values apply. -
FYI: Graph showing iOS crashes with recent Delphi versions
Dalija Prasnikar replied to Hans♫'s topic in Cross-platform
I understand how you feel. Sometimes it is going two steps forward three steps backward. One of the problems with cross-platform development is that not all code is the same. And different principles apply. OS architectures are different and what you can do on one platform, you cannot do on another. I am talking generally, regardless of whether offending code is yours or Embarcadero's. Also mobile platforms change frequently and are also changing rules and behaviors. What worked today, may break tomorrow. This is not related just to Delphi applications but all. I am using Xcode - Swift and Android Studio - Java for mobile development and situation is not much different. The only difference, is that when some policy or behavior changes, you immediately have appropriate tools to implement change. But your code will be broken left and right. You cannot take year old code and make simple recompile - in Swift everything is in a state of flux - language, frameworks, so every time you touch it, it is almost a rewrite. I don't even know what is the proper method for sorting list - its name changed dozen times - from sort to sorted to sort again... what is current one I have no idea - and that is just the simplest example. On Android, Java is the same, but frameworks are changing every week. If you have to support newer versions of OS, you have to use newer frameworks, that also change all the time, are buggy as hell... I know Delphi could and should be better. But, I also painfully know that grass is not greener on the other side. What we can do, is relentlessly report issues to Embarcadero. Not all will be fixed and not all will be fixed as fast as we would like, but Embarcadero is fixing them. Especially, more critical ones. -
FYI: Graph showing iOS crashes with recent Delphi versions
Dalija Prasnikar replied to Hans♫'s topic in Cross-platform
Quick search through Quality Portal didn't reveal any reported issue similar to yours. Can you please file QP report. -
FYI: Graph showing iOS crashes with recent Delphi versions
Dalija Prasnikar replied to Hans♫'s topic in Cross-platform
On Windows, yes. On other platforms not so much. Android and especially iOS are just sitting and waiting for opportunity to nuke your app. -
FYI: Graph showing iOS crashes with recent Delphi versions
Dalija Prasnikar replied to Hans♫'s topic in Cross-platform
Not necessarily compiler, but RTL/FMX or other frameworks. Yes, there were some changes in compiler that may have influence, but such errors tend to have impact across all platforms. Now, it would be interesting to figure out what exactly is the problem. -
FYI: Graph showing iOS crashes with recent Delphi versions
Dalija Prasnikar replied to Hans♫'s topic in Cross-platform
Do you have any information about iOS versions used? At some point (around version 11) iOS became more sensitive to touching UI from background threads. I had small test apps built with Tokyo and Rio that were happily running on iOS 9.x and were instantly killed on iOS 11.x. -
1. Because they have full control and can do with it what suits their needs the best 2. Dogfooding 3. They also have IDE for Mac - Fire (and that was first one they wrote - AFAIK when they started that project there was no VS for Mac) - Water is just Windows variant to prove cross-platform viability of their approach 4. Here we were talking about VSCode that fits nicely for some things (not VS), but still is resource hungry Electron app. I don't know about Water, but Fire is native Mac application - which means fast. 5. When it comes to VS itself and VS being so nice... I don't know. Last time I used it it was dog slow comparing to Delphi IDE (around XE time). 6. Having plugins for various IDEs can be nice and certainly is good place to start when you are just starting - but nothing beats fully dedicated IDE under your control.
-
version control system Version Control System
Dalija Prasnikar replied to Soji's topic in Delphi IDE and APIs
I would suggest Git or Mercurial. Mercurial is a bit easier to learn and most of the time prevents you from shooting yourself in the foot. TortoiseHg works great and fast. Git is more powerful, but has steeper learning curve And I still have to find Windows Git client that actually works. On Mac SourceTree works fine, on Windows not so much - slow beyond description.- 49 replies
-
- git
- subversion
-
(and 1 more)
Tagged with:
-
Should my record be a class instead?
Dalija Prasnikar replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Using classes just for the sake of using classes can be nice exercise in futility. I have to admit that I haven't paid close attention to this post and I have been reading it rather superficially, so it is possible that I missed some piece. But from your original post I don't see any compelling reason why you should switch to classes. Especially if you don't feel comfortable with them and don't really see the point. Main advantage of classes over records is polymorphism. If you don't have the use case for it, then records will do. Also, one small note - you are holding your records in dynamic array, and those are allocated on the heap, not on stack. Only the few bytes of your global record holder would sit on stack. And overall, class based solution would use more memory than record based one. That does not mean that you should not learn more about the classes, but trying to learn on wrong use case will make things harder not easier. You should learn about classes with examples where they really show their advantage and then you will be able to understand them better.