Adobe Photoshop 1.0.1 Source Code (2013)
computerhistory.org
computerhistory.org
The goal was to move the COBOL, Fortran, JOVIAL, and assembly language programmers in the company to Pascal. My department built the compiler and because I had taught programming in grad school I ended up being one of the evangelists that taught innumerable one week crash courses to the company’s engineers, business programmers, and software people. It was actually a really fun job and I met a large number of people that worked in the company’s various branches.
I discovered that there is no better way to learn every facet of something than to teach it, more than once, to grumpy students sceptical of the new fangled concepts.
A couple years later I was back in grad school again, still programming in Pascal. It was interesting to realize that most fellow PhD students that go straight through aren’t really good programmers and don’t understand software engineering. (This was a long time ago so it’s probably very different now. CS students own their own computers and are able to program much more than we could.)
I remember Pascal fondly like some friends remember their first car. Like cars though, the new languages are really much better (safer, faster, more reliable, etc).
As a recent CS undergrad and current software engineer in a research organization, I don't think it is. Most of the people I worked with on group assignments in my undergrad had, at best, a limited understanding of their prior coursework, much less any knowledge acquired on their own time. Furthermore, CS PhDs in my org don't know anything about software engineering and mostly don't care. They are really here to do math. They don't need to write good code because I can transform their mediocre (from an SE perspective) code that handles the base case of a complex algorithm into better code that is maintainable, handles error cases and integrates with the rest of our codebase.
But one thing my school did perfectly, is force 3 months of internships per year, and leave at least 1 day per week without classes (and 2 days for the last 2 years). There is nothing better for learning than experience. The first 2 years I did unpaid internships, by my third year I knew enough to get paid 20$ / hour working part time. By my last year of school I was making 35$ / hour 2 days per week without even having a degree, that's over 2400$ while I was still studying 3 days a week. And not only money, I got a lot of hands-on experience.
John Knoll is a name that may be familiar to people who stick around after the credits; he was ILM's supervisor on Generations and First Contact, all the Star Wars prequels, some Harry Potter movies, as well as some of the Pirates of the Caribbean movies. His name comes up a lot in behind-the-scenes interviews etc. with directors about effects.
- plain JavaScript/jQuery to React
- Ruby on Rails/Node.js to Golang
Many people might dismiss the former as an inferior language, but the point is, you might not have enough time to write a successful software in latter given the time and window of opportunity. And the initial boost of productivity with a simpler language might be important.
Of course the reverse can be bad as well when you have an unmaintainable 50k lines jQuery app and nobody wants to rewrite that with a proper framework.
I recently read an article on Flutter comparing to native Android layouts, and thought to myself: Delphi has had a x-plat framework that does all that, and more, in less lines of code, for six years.
(*) Disclaimer: I work for the company that makes Delphi. I do that because I think it and its sister C++Builder are great products and want to see it better-known.
But we can't have nice things.
But my budget for hobby projects is $0, and a time-limited trial isn't useful. Therefore I won't try it, and I won't be advocating it to anyone else either.
Only with UWP and C++/CX did Visual C++ finally gotten visual, and it still doesn't do as well as Builder.
I like Autodesk's license for Fusion, it's free to use (the full version) until you're making $100,000 in yearly revenues, after which it costs some amount of money. If I were making $100k in revenues (and probably well before that), I would happily pay for the tool that's making me money, but paying 3x my revenue for the IDE/language is hilariously prohibitive. There's also no way in hell I'm going to spend $3000 for a hobby project that may or may not make $100 during its lifetime.
It's too bad, too, because I remember how easy and quick developing in VB4/VB5 was, so Delphi sounds great on paper, and I would definitely use it to develop at least some applications if it weren't so expensive.
I have been having these thoughts for the past few weeks. After the watching DHH's RailsConf Keynote and thinking about Conceptual Compression, and current technology. Why have we made everything 10x more complicated over years. It is not just Web Sites, Apps as well. VB may be ugly, but it lower the entry barrier. ( VB.Net is an entirely different thing ). Delphi literally have everything done right for well over a decade and it's idea and philosophy aren't being copied anywhere.
Instead of making software easier for everybody to learn, easier to maintain and less prone to bug, making debugging easier, higher performant and less recourse hungry. We have managed to bloat the framework, the languages, the CPU and memory resources, trillion times more abstracted. Everything is a hack over another hack.
If we could keep the great dev tooling and UI toolkit, but use a language with a larger ecosystem, that would be much more impactful. Maybe Python + Qt can be the answer to that.
Delphi was awesome through 7.0. I didn't really track it after that, but I was a Delphi programmer for several years from release onwards (happened to come from a college that taught Pascal for the first year of CS), then worked for Borland on Delphi/C++Builder for a couple of years after that.
Borland really mishandled their language stack by alienating all the grassroots. Nothing against the later owners, but Delphi's pricing became absurdly tilted towards legacy enterprise projects.
Lazarus was mentioned earlier. Think they're fully compatible with the 7.0 state of things, which was decent. It's worth checking out for project prototyping, etc.
Edit: it seems that it was written in delhi and they rewrote it in C#
"When you're writing desktop software, there's a strong bias toward writing applications in the same language as the operating system." --pg
Would I be correct in assuming Photoshop was converted to C/C++ around the same time that its target platforms were?
Adding to the list, lambda-the-ultimate.org itself is written in Drupal/PHP.
It's not, imagine the site with editorialized titles. It'd be a roiling, infinite pool of lava.
MPW (Macintosh Programmer's workshop) was pretty awesome, if slow as hell -- Turbo Pascal was a lot better to work with -- the only issue is that it 'tokenized' your source code, so it wasn't plaint text anymore...
I still miss these 'one pass' compilers; I think it peaked with MetroWerks toolchain (which kept a Pascal plugin for a long time!) that was IMO the best compiler/linker/debugger toolset ever made.
However, MPW still holds one of my best programming experiences: I discovered it quite late, on an iBook, shortly before Xcode introduction. On MPW I wrote a simple cli math calculator, where you type your full equation like in a notebook – implementing an array walk with pseudo-regex. MPW was simple enough and clear enough that it was the first moment I thought I could really handle coding.
I take you are not color blind (I never considered it bad at any rate). Also it was configurable, iirc
It's a bit odd: there's no brackets at all (only BEGIN and END), and the majority of names (functions and variables) are 6 characters long.
Guess what, it's was ported from Pascal. There's a '#define BEGIN {' in a header.
QuickDraw began life in 1979 written by Bill Atkinson in Pascal and still ships in MacOS High Sierra. Photoshop originally lifted its main design metaphors and toolbar icons from Atkinson's (and Susan Kare's) MacPaint.
MacPaint and QuickDraw source code: http://www.computerhistory.org/atchm/macpaint-and-quickdraw-...
Recent long-form interview with Bill Atkinson: https://www.youtube.com/watch?v=6tUWoy1tJkE
Which was actually C++, given that they tried to port MacApp to C++.
While at the same time Metrowerks, which was the major compiler vendor on the Mac, introduced PowerPlant.
https://en.wikipedia.org/wiki/MacApp
https://en.wikipedia.org/wiki/PowerPlant
https://archive.org/stream/ApplePascalHistoryDTC92/ApplePasc...
Comments at http://blog.fogus.me/2017/07/20/pascal-at-apple/
So plain C always had very little place at Apple, even at NeXT it was all about Objective-C and Objective-C++, including the driver framework.
Both A/UX and NeXTSTEP used UNIX compatibility as a means to bring software into the platform, but the goodies were in the platform specific frameworks.
> So plain C always had very little place at Apple, even at NeXT it was all about Objective-C and Objective-C++, including the driver framework.
That was at NeXT in the late 80s and only came to Apple after Amelio bought NeXT to use NeXTStep as the Classic Mac OS followup.
Apple shipped their first C compiler with MPW 2.0, released on July 20, 1987.
Turbo Pascal later fixed those issues, still on MS-DOS.
On Apple as they switched focus to C++, they left the Pascal support stagnate.
Metrowerks only appears quite late, with the PowerPC macs -- I remember having both a prototype of the PowerPC 601 66Mhz pizza box and the fancy new compiler on the block delivered from apple (I remember the excitement -- that sort of excitement new tech delivered that I never really found again after that decade!). I stayed on the 'permanent beta list' of metrowerks until they vanished.
Before that, THINK C/Symantec C/C++ existed and were in use extensively including inside of apple, but most of the software was plain C, or "base C++" (it was before the time of templates and stuff like that) at best...
Apple never used C++ for system interfaces. Even 'Carbon' on OSX still used Pascal Strings for the historycal toolbox calls. Over the years they added extra helpers and extra glue code to cater for C, but they stuck more or less to their API design until OSX arrived.
The funny bit is that even afterward they continued with some of their paradigms, the 'component' one for example, was still in used for years afterward for quicktime stuff, in OSX. Likewise the AppleEvents (also using "components") had the same paradigm and structures as it ever had (and migth still have!)
It was unthinkable for most business in Portugal to get a Mac, given that there was only one official importer, Interlog, with shops in Lisbon and Porto, nowhere else.
So I had the idea the C++ frameworks were introduced as the same time as the C, C++ SDK, not was system interfaces, but as wrappers on top of them.
... eh ? https://developer.apple.com/library/content/documentation/De...
Beside, despite the syntax sugar, it is NOWHERE near C++ at all. No constructors/destructor (if I remember correctly), no stack based objects, no exceptions, no virtual functions, no library, and you had to provision your classes with the right number of member function 'dummy' pointers to allow for expansion. I've written enough OSX drivers back then to know that, quite frankly, C would have been a lot better.
I think that you are fairly mistaken. IOKit drivers are written by inheriting from a base class and overloading virtual functions.
Here's how it looks : https://developer.apple.com/library/content/documentation/Da... ; it may be not 2018 template-metaprogramming bliss, but it's fairly standard C++.
Initially I was really excited to write some code and give Photoshop some super powers. Especially I wanted to make a panel for automatic layout, and another for generative art.
But in the end I realised that Photoshop is just not designed to be extensible other than in some very specific ways (filters mostly).
I was also convinced that even Adobe probably has trouble putting in new features. This was surprising knowing that most of Photoshop's features don't interact with other features in any way (unlike a word processor or a 3D design suit like Maya). They can even develop the features in silos if they want to. But still, the extension APIs give some strong hints that the whole thing is tangled and unwieldy [1].
I did try to tame the thing [2] but the whole process was so unstable that after a few months of part time work, I just gave up. My conclusion was that if you want to have a design tool with super powers, you can't build it on top of Photoshop (or any of its competitors for that matter).
Anyway, this is where I shamelessly self-plug and say that I decided to start a company to build such a tool myself. Write to me [3] if you would like to learn more ;)
---
[0] This was one popular extension I wrote: http://gelobi.org/griddify
[1] I didn't care enough to document this, but I'm sure there are other extension developers who agree.
[2] https://github.com/AriaMinaei/photoshopjs-com/blob/25c320f83...
[3] aria [at] theaterjs.com
I take it you meant independent teams? If so, I did acknowledge that. In fact, the whole interaction model in Photoshop allows it to be developed by independent teams that don't need to communicate much (this is at the expense of some major UX opportunities imho).
> How things work under the hood can end up very different from the API
I was lead to my conclusion despite knowing that.
var idMk = charIDToTypeID( "Mk " );
var desc7 = new ActionDescriptor();
var idNw = charIDToTypeID( "Nw " );
...Meanwhile, the Think Class Library (C) was designed and written by an individual .. a name given after the group behind Think-C / Lightspeed C got behind it.. The lone designer of the original Think Class Library is named Gregory H Dow.
It is a subjective statement, but I believe that more than four times the number of big name Macintosh apps were written in Think Class Library, in C, than Pascal MacApp from Apple.. There was a big interest in C for the Macintosh, while Apple repeatedly pushed their own Pascal, until Apple could control their own C compiler in the Macintosh Programmers Workshop (MPW). (edit- MPW C existed internally at Apple for a long while, but there was some disconnect between that and the developer tools marketing)
Gregory H Dow then designed and built a second generation framework using C++, called PowerPlant for Metrowerks CodeWarrior. PowerPlant was used for many, many more commercial applications after that. Pascal faded away on the Macintosh OS, even with the forceful support of Apple.
I also find comments do get in the way when they state the obvious, unless they add to the understanding of the code in some way it is best to leave them out IMHO.
if (status != 0) return -1; // return on error
I always get angry when I find comments like this in our codebase.I prefer that authors spend time to make sure the code is clear about what is happening, and use the comments to tell me why it's happening, and that too only when it's not obvious, or counterintuitive, or there for a special requirement.
Just wanted to point out that comments are not to be confused with documentation as comments, like Javadoc, Godoc strings. These need to be complete and verbose, especially if they code is a library or public.
-1 could mean you're returning a success. I mean that would literally be true in Forth.
Specifically, the message says "return on error", which to me doesn't mean it returns an error, but to you it did.
Also, you are likely to find out that comments like this are often result of people just auto-writing them at the moment e.g. writing it was faster then reflect on it. Which is not necessary good thing, but it is saving time in expense of little bit less effective code.
Regarding time saving, I seriously doubt that code quality is proportional to time spent typing. Instead of typing two things I would prefer the author spent more time thinking and typing just one thing.
// based on stackoverflow.com/questions/201323/how-to-validate-an-email-address-using-a-regular-expression
because I'm not going to pretend to have written this monster myself:
(?:[a-z0-9!#$%&'+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'+/=?^_`{|}~-]+)|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])")@(?:(?:[a-z0-9](?:[a-z0-9-][a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-][a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])
I've only ever done it with stackoverflow because:
1. I think they'll be around for a long time, and 2. they have that policy of explaining answers on the page rather than just referring to external links (yes - irony not lost on me).
Any future dev looking at my 3-line validateEmailAddress() function who wants to learn about it can go to the site and read about it, and maybe find there's a newer status quo way of validating email addresses.
I suppose you could argue that I should copy the explanation of what the regexp does into the comment but really it's just asking for it to become redundant and if someone really wants to get into it they'll probably benefit from reading the entire up-to-date discussion.
Admittedly this is a very specific kind of situation, but this doesn't feel unreasonable or unprofessional to me (bearing in mind that I'm not generally a copy-paster, I prefer to write my own code but in the case of things like email validation I think it's more professional to find an established algorithm than it is to roll your own, unless you have a specific reason for doing so).
This tends to only be for tricky or time-consuming algorithms. RGB to HSL/HSV, is point in a polygon, hash function, etc. Those point-in-polygon functions in particular can be densely optimized to the point that it is not obvious a) how it works, b) what the original algorithm was.
That is why. The person left comment on literally one thing in that code he is able to explain.
if (status != SUCCESS) return ERROR; // return on error
then you'd have a problem. i++; // Increment by 1Especially in Java code - look at Android for example. Loads of "setFoo() // sets foo" nonsense.
But in general I think people use the "code shouldn't need comments" thing mostly as an excuse to be lazy and not write comments.
[0] https://github.com/behdad/cairo/blob/color-emoji/src/cairo-p...
But then I scrolled down and saw it verbatim just a few lines further down https://github.com/behdad/cairo/blob/color-emoji/src/cairo-p...
Why is CheckMitreHight() not a function? :)
/* img "doc/uml.png" */
or something similar that it would use to display an image inline with my source code. There are so many times I've created a FSM diagram with graphviz + dot that I'd love to include inline.I'm sure you can find similar extensions for VSCode or Atom.
Seldom people document the 'Why' which is the most useful some years in as no one knows the 'Why' any longer and might make the wrong decisions in refactoring - also if you don't know the 'Why' you often scratch your head with WTF, though the reasons were sound.
"How" though, very much e.g. reference to the algorithm being implemented or the like if the code is unclear.
Not to mention the misery one feels when they discover that oh, there is in fact no reason at all, or if there ever was, it is now truly lost.
More often than not, you only need a few jumps before reaching the change you're interested in.
I have a 1500LOC files with 1100 revisions right here, "git annotate" processes it in 2.356 seconds on a 2010 MBP, and PyCharm barely takes any longer (maybe 3s).
> How is my IDE supposed to know which of those revisions are the ones that I care about?
It does not care, it gives you a baseline annotation and if that's too recent you drill down into previous annotations.
No thanks. I’d rather have a comment inline in the code than add 3 seconds per file, and still have to go searching through the history.
Or as I've encountered on multiple occasions: your IT team is struggling to figure out why your network/version control/etc are extremely slow... 3 second queries are now taking 60 seconds... we will be rebooting servers a few times... and restoring backups... hopefully things are working better tomorrow!
Or what happens when you migrate to another versioning system? Where I was working migrated from MS SourceSafe years ago and a lot of comment history was lost in the conversion and apparently it wasn't worth the time/money to figure out why only half the comments made it over.
I'm sure there are more scenarios.
The point is: comments in plain-text source files can be invaluable.
Which is exacerbated by everyone's IDE now querying VC for every file!
That's what annotate/blame is for.
> Not to mention the misery one feels when they discover that oh, there is in fact no reason at all, or if there ever was, it is now truly lost.
If there was "no reason at all", it won't be in a comment either.
Except you can't trust comments. Even assuming the comments were relevant at one point, they don't get updated as the code changes, and as new code gets added they can drift away from the original code they were supposed to explain.
Commit messages don't drift, they're immutably bound to the changes the commit performs.
And because they're not bloating up the code it's much easier to be clear and verbose in commit messages than it is in comments, the author can easily explain things which seem obvious to them but may not be so for a reader in a few months or years without lowering the overall readability of the code which is not the case of comments.
People will criticise comments as "obvious" and "unnecessary", I've yet to have a colleague or contributor criticise a detailed commit message for any other reason than the commit message being wrong.
> It should not be detective work to figure out why some code is written in a non-obvious way.
Get proper tools. Browsing annotations and reading commit messages is not "detective work", it's absolutely straightforward and means you're actually using your VCS as something more than a glorified tarballs directory.
That works until the VCS history is lost. For an on-topic example, this usually happens when a formerly closed-source code is released to the public: only the final state of the source code is released, with none of the VCS history. This can also happen when changing to another VCS; often the history is kept only on the former VCS. Some projects have gone through several of these events; I challenge you to find early StarOffice history when trying to understand why some piece of LibreOffice code is written that way.
And there's also the tendency in some places to reference bug tracker issues in commit messages. Said bug trackers tend to have an even shorter life than the VCS. "Fixes issue #1234" is useless when issue 1234 was on the old bug tracker, and both it and the new bug tracker were lost when the company was acquired and migrated to a third bug tracker.
Comments you can at least make an effort to keep up to date. Especially if have a policy that all comments should actually be relevant.
Comments shouldn't be obvious and unnecessary. They should explain things which cannot be inferred from the code itself, eg,
// have to call reset() twice here because the XZW API has a bug which restarts the server if reset is not called twice. See ..."Doing this here because x,y,z, maybe better to do a,b,c later on but would have to do d,e,f" and so on.
I do worry a bit about doing it sometimes because in its own way it admits some sort of shortcomings or such... but still I do it.
When reading other people's code the why is often the question I'm wondering but rarely anyone says.
e.g. This is the kind of thing I find myself wondering very often while browsing our company's codebase:
"Why are we only appending the jurisdiction on this partner and not the others? Is this intentional or an oversight? Maybe the unit tests will tell me more..."
Even if it blends over a little into integration testing, the additional test work (and time to run tests) really pays off in terms of understanding and reusing an old project.
Besides being cleaner, when you add the next vendor, you won’t be searching all over the codebase for if(vendor)’s to add new special cases.
I'm basically of the same persuasion. Multi-line comments don't belong in the body of code, single line comments are sometimes necessary but I strive to eliminate them through more self explanatory code (although I will prefer a one line comment over unwieldy long variable names which often outweigh their worth by reducing legibility, especially when talking math).
Beyond that the only good reason I've found for large multi-line comments are when even given the best implementation: when there are subtle details in the concept you are implementing that can appear as being redundant or superfluous in the implementation, it is very important to comment to remind yourself not to break it when next trying to digest it again.
Whatever are your opinions on comments, this file breaks them all with a good reason behind each. And it's still implementing a standard which should be fairly well defined, but... isn't.
So yes, multiple comments explaining code, explaining behaviour, reproducing relevant parts of the standard, and many others. The code both requires them to know wtf is going on, and at the same time is pretty close to simple as far as multithreded SIP can go.
// gives a thumbs up
user.thumbsUp();
Saves a lot of time vs jumping to the definition to see what it does
http://www.drdobbs.com/a-conversation-with-john-knoll/184410...
Including:
> Thanks to Steve Dorner, Jeff Beckley, and John Noerenberg for their encouragement and participation in this multiyear odyssey to release the code, and for creating Eudora in the first place. You should be very proud of what you did.
edit: I mean it is weird because this was released in 2013 and it has acknowledgements of a another current release. Seems like a template change or something similar.
Why? I'm not sure, but maybe: (1) there is less functionality, so less stuff on the screen. (2) Black and white means that the icons are all high contrast. (3) the icon shapes are simpler (compared to Gimp's toolbar icons). (4) the borders on the forms are higher contrast; in Gimp's color picker form, for example, the boxes surrounding places where you can type stuff in appear to be gray, whereas they are black in these early Photoshop pictures.
NB: I recently downloaded a copy of Turbo Pascal 1.x and been messing around with it in a DOS box on the Win7 laptop again. No idea where that source code I wrote 40 odd years ago is now, and no way of getting it off any sort of medium it might have been on either!
https://github.com/linker3000/Historic-code-PC-Pascal-and-AS...
I used Turbo Pascal at work in an electronics R&D lab - my biggest achievements were a staff time management program and one that 'drove' a Stag EPROM/PAL/device programmer, so a dev could just point to a device firmware text file in one of a number of formats (Intel Hex etc.) and it would be parsed for errors, sent to the programmer, the right device selected, programmed and verified - this saved a lot of fiddling with the programmer itself.
Programmer was similar to this: http://matthieu.benoit.free.fr/Stag_PPZ_Zm2500_programmer_re...
I don't have that source code any more but I somehow managed to use TP for some home projects too!
Happy days!
The more things have changed, the more they've stayed the same.
Funny thing is Pascal was seen as the constraints language at that time, while C was more liberal. Different times.
In Pascal evolution (Delphi and Lazarus), a lot of automatic memory management, including proper gc but most often simple referemce count, has been incorporated over the years. Also the memory for a lot of standard library resources is managed hierarchically.
In short: You still need to know how to deal with memory manually, but most of the time you don't.
The big difference with C is that you need to be explicit that you are going to do something that might go wrong.
For example, arrays and strings have bound checking.
If you want disable it, you can, either via compiler switch, or a pragma like {$R-} and {$R+} around a code section.
Likewise you don't need pointers for out parameters, because references are supported as well.
Pointer arithmetic is possible, but first you need to convert the address into a pointer type, then you can manipulate it like on C.
Enumerations are their own type, instead of being implicit numbers, without any check if they can be converted back.
It had a raft of issues though, chiefly a lack of dynamically sized arrays and strings ("pascal strings" combine a static maximum size of no more than 255 with a single-byte actual-length prefix, IIRC all on the stack) or rudimentary dependent typing making generic processing of these extremely difficult[0], no ability to break (out of loops) or early-return, undefined order of evaluation of boolean expressions (and/or), … Kernighan actually wrote an entire "Why Pascal is Not My Favorite Programming Language" essay in '81
More modern evolution have related/fixed some of these since, not necessarily in great ways (freepascal's "String" can use one of 3 different string implementations depending on compiler settings & active pragmas[1], and that's a small subsets of the actual stable of string implementation available)
[0] outside of builtins (which weren't limited to the language's "user" semantics much like Go today) you'd need an implementation for each static length of array/string
[1] http://wiki.freepascal.org/Character_and_string_types#String
Many modern frameworks still aren't as nice to use.
As a point of contrast, Microsoft shipped a similar sort of TUI framework with its Microsoft BASIC 'Professional Development System'. The PDS was Microsoft's original BASIC compiler (BASCOM) that'd had been integrated with the QuickBASIC (4.5?) IDE. In addition to the compiler, the PDS had direct ISAM support and a few other higher end features targeted at people writing enterprise line of business apps.
The TUI framework was their attempt to allow developers using the PDS to write applications in the same visual style as the IDE itself. However, due to the fact that the underlying BASIC language had neither objects nor function pointers, there was no way to implement any sort of callback model in the API. The net result was a framework that required huge amounts of boilerplate code to get anything done and was virtually impossible to use. So, while TurboVision was a bit harder to wrap your head around, it at least had the benefit of being actually commercially useful once you did.
This is a big part of why I tend to strongly prefer development tools that are actually used by their developers. The incentives are aligned.
* https://embarcadero.com/app-development-tools-store/delphi
* https://embarcadero.com/app-development-tools-store/cbuilder
There are lower-cost "starter" editions, that however have restrictions on use.
* https://embarcadero.com/products/delphi/starter/info
The feature matrix is 37 pages long. There's all sorts of stuff in there. For examples: UML is Delphi-only. Some tools for debugging multi-threaded programs aren't in the "starter" flavours. Nor is the ability to debug any process; nor to run until function return; nor for targetting Win64.
Nevertheless, if you consider that $1500 is less than a week's salary for a programmer, you just need to work out whether a $1500 tool is going to save you a week of programming time. Back in the day I was using the heavily discounted education edition as I was a poor student; many products still have something like this (for example JetBrains' suite is free for students and OSS projects). But the price itself isn't really that much in the scheme of things.
Nevertheless, if you consider that $1500 is less than a week's salary for a programmer, you just need to work out whether a $1500 tool is going to save you a week of programming time. Back in the day I was using the heavily discounted education edition as I was a poor student; many products still have something like this (for example JetBrains' suite is free for students and OSS projects). But the price itself isn't really that much in the scheme of things.
There's also Lazarus - an OSS delphi clone
It is pounds, not dollars. And no it isn't.
*in a pure structured language each statement sequence is either fully executed or not executed (there are no goto-like statements)