NYCJUG/2017-01-10
Beginner's Regatta
Removing Trailing Zeros
When converting numbers in J to a text form in order to export data to an external system, we sometimes encounter the problem that the default format verb falls prey to floating-point imprecision display issues. I most recently encountered this working with some verbs to display points in an interactive, 3D HTML format, motivated by this essay (http://code.jsoftware.com/wiki/Essays/Christoffel/Christoffel01). When converting a set of points to a text format to put in an HTML file, I ran into this problem that made the file much larger than it needed to be:
$chrispts 8000 3 2{.chrispts 0.5 0.15708 0.15708 0.5 0.15708 0.223218 cvt2d3Array 2{.chrispts [0.5000000000000000,0.1570796326794897,0.1570796326794897],[0.5000000000000000,0.1570796326794897,0.2232184253866432] Looking at an existing verb I have to deal with trailing zeros, I noticed it has a bug. It works fine for a set of numbers like the ones here that all have decimal points but fails for a simple test case: detrail0 &.> j2n &.> 2{.chrispts +---+------------------+------------------+ |0.5|0.1570796326794897|0.1570796326794897| +---+------------------+------------------+ |0.5|0.1570796326794897|0.2232184253866432| +---+------------------+------------------+ samp=. '0.5000';'0';'0.0';'0.4500';'0.02340';'100';'101' detrail0 &.> samp +---+-+--+----+------+-+---+ |0.5|0|0.|0.45|0.0234|1|101| +---+-+--+----+------+-+---+
We see that I’m not checking for trailing zeros following a decimal point. We could try rounding these numbers to 4 digits past the decimal as this should not matter for display purposes:
almost=. j2n &.> <.0.5+1e4*0.0001 roundNums (i.3)+"(1) 2{.chrispts (_4}.&.>almost),&.>'.',&.>_4{.&.>almost +-----+------+------+ |.5000|1.1571|2.1571| +-----+------+------+ |.5000|1.1571|2.2232| +-----+------+------+
However, this seems unsatisfactory as a general rule, so I set out to do a better job starting from this point:
roundedJ2N=: 3 : 0"0 0.0001 roundedJ2N y : detrail=. (] {.~ ([: # ]) <. [: >: [: i:&0 '0'&=) :(] {.~ ([: # ]) <. [: >: [: i:&0 =) almost=. j2n &.> <.0.5+x%~x roundNums y ntd=. -<.0.5+10^.%x NB. Number Trailing Digits almost=. (ntd}.&.>almost),&.>'.',&.>ntd{.&.>almost almost=. detrail&.>(('.'={.&>almost)#&.><'0'),&.>almost almost,&.>('.'={:&>almost)#&.><'0' )
This appeared to work with our initial set of points but fails for a couple of simple test cases:
roundedJ2N chrispts{~2{.nix +----+------+------+ |5.5 |1.3476|0.6862| +----+------+------+ |6.0 |1.083 |1.1492| +----+------+------+ roundedJ2N 1 _1 1*"1 chrispts{~2{.nix +----+-------+------+ |5.5 |-1.3476|0.6862| +----+-------+------+ |6.0 |-1.083 |1.1492| +----+-------+------+
Starting over from first principles eventually led to this solution:
detrail=: 3 : 0 NB.* detrail: remove trailing {.x after {:x '0.' detrail y NB. 0s after '.' : whd=. y i. {:x NB. Where decimal point is if. 0~:#decimal=. whd }. rr=. y do. NB. If anything after decimal nt=. ({.x) ([: +/ [: *./\ [: |. =) decimal NB. Number of trailing items nt=. -nt+nt=<:#decimal NB. Also drop decimal point if only all trailing after it rr=. (whd{.y),nt}.decimal end. rr NB.EG '50.05';'0.5';'0';'0';'0.2';'100';'101'-:(<'0.')detrail &.> '50.050';'0.5000';'0';'0.0';'0.20';'100';'101' )
Note the “NB.EG” comment in the last line which gives an example test case. However, further testing revealed a slight problem with this example even though the result appears to be correct:
detrail '50.050';'0.5000';'0';'0.0';'0.20';'100';'101' +------+------+-+---+----+---+---+ |50.050|0.5000|0|0.0|0.20|100|101| +------+------+-+---+----+---+---+
However upon running the test we see that the equivalence does not hold:
('50.05';'0.5';'0';'0';'0.2';'100';'101')-:detrail &.> '50.050';'0.5000';'0';'0.0';'0.20';'100';'101' 0 Closer examination reveals the source of the discrepancy: ('50.05';'0.5';'0';'0';'0.2';'100';'101') = detrail &.> '50.050';'0.5000';'0';'0.0';'0.20';'100';'101' 1 1 1 0 1 1 1 The problem is in the statement of the test case: ('50.05';'0.5';'0';(,'0');'0.2';'100';'101')-:detrail &.> '50.050';'0.5000';'0';'0.0';'0.20';'100';'101' 1
Show and Tell
Examples of the Schur Complement
Searching for numeric examples of the Schur complement yielded no results, so I decided to remedy this by providing some examples in J. Here is the basic definition of the Schur complement from "Special Matrices and Their Application in Numerical Mathematics" by Miroslav Fiedler:
Setting up a partitioned matrix A:
]A=. 2 2$(2 2$1 2 3 4);(2 2$1 10 0 20);(2 2$_1 2 3 _4);<2 2$_2 _3 5 _9 +-----+-----+ |1 2 |1 10 | |3 4 |0 20 | +-----+-----+ |_1 2|_2 _3| | 3 _4| 5 _9| +-----+-----+ We can then assign the parts of this to match the definition given: 'A11 A12 A21 A22'=. ,A A11 1 2 3 4 A22 - (A21+/ . * %.A11) +/ . * A12 NB. Schur complement of A in M: M/A _7 _13 17 11
How do we know if this is correct? As I said, I could find no worked-out, numerical examples so we’ll have to test it some other way. One hint on how we might do this comes from one of the subsequent theorems in this book:
Assign our expression for the Schur complement to SC and find its determinant:
SC=. A22 - (A21+/ . * %.A11) +/ . * A12 NB. Schur complement of A in M. -/ . * SC 144
Now unpartition mm and find its determinant:
,./;"1 |:A 1 2 1 10 3 4 0 20 _1 2 _2 _3 3 _4 5 _9 -/ . * ,./;"1 |:A _288
Check that the equality in Theorem 1.4.2 holds:
-/ . * A11
_2
(-/ . * SC) = (-/ . * ,./;"1 |:A)%-/ . * A11
1 However, a single match proves very little. Lets try with some randomly generated matrixes. It’s simpler to generate the unpartitioned full matrix, then partition it, so we do this:
]mm1=. 100-~5 5?@$201 6 _24 _65 _93 _92 _71 35 _51 _49 40 29 _99 _55 _72 71 25 _4 _77 _61 _87 44 _23 _12 _4 _92 ptn=. 1 0 0 1 0 (ptn;ptn) <;.1 mm1 +-----------+-------+ | 6 _24 _65|_93 _92| |_71 35 _51|_49 40| | 29 _99 _55|_72 71| +-----------+-------+ |25 _4 _77 |_61 _87| |44 _23 _12 | _4 _92| +-----------+-------+ 'A11 A12 A21 A22'=. ,(ptn;ptn) <;.1 mm1 A11 NB. Sanity check 6 _24 _65 _71 35 _51 29 _99 _55 ]SC=. A22 - (A21+/ . * %.A11) +/ . * A12 NB. Schur complement of A in M: M/A 63.427 159.504 29.508 24.1838 (-/ . * SC) = (-/ . * ,./;"1 |:mm1)%-/ . * A11 NB. Does det(A/A11) = det(A)/det(A11)? 1 <pre> Since the original definition mentioned that M does not need to be square, let’s also check that case: ]mm1=. 100-~5 5?@$201 NB. Random matrix 76 _47 _36 _89 _66 _48 _49 _26 _36 _6 72 _42 62 _3 _1 87 _49 94 20 19 25 86 27 15 _44 ptn=. 1 0 0 1 0 NB. partition unevenly 'A11 A12 A21 A22'=. ,(ptn;ptn) <;.1 mm1 ]SC=. A22 - (A21+/ . * %.A11) +/ . * A12 NB. Schur complement of A in M: M/A 6.65626 7.7254 _54.7328 _68.5447 (-/ . * SC) = (-/ . * ,./;"1 |:mm1)%-/ . * A11 NB. Does det(A/A11) = det(A)/det(A11)? 1
Another non-square test:
ptn=. 1 0 1 0 0 'A11 A12 A21 A22'=. ,(ptn;ptn) <;.1 mm1 ]SC=. A22 - (A21+/ . * %.A11) +/ . * A12 NB. Schur complement of A in M: M/A 94.5405 78.3552 59.9953 132.236 116.253 91.6421 _24.0023 _74.6259 _83.7766 (-/ . * SC) = (-/ . * ,./;"1 |:mm1)%-/ . * A11 NB. Does det(A/A11) = det(A)/det(A11)? 1
Another test using the latter part of Theorem 1.4.2:
'B11 B12 B21 B22'=. ,(1 1;1 1) <;.1 %.1 2,:3 4 NB. Partition inverse ]SC=. B22 - (B21+/ . * %.B11) +/ . * B12 NB. Schur complement of A in M: M/A _2 SC -: %.B22 NB. [A/A11] = %.B22 1
Advanced Topics
Style by Dan B.
In the following email, Dan Bron proposes some style guidelines for displaying J code.
[Jprogramming] Style guide 'Jon Hough' via Programming <programming@jsoftware.com> / Mar 16, 2016 / to Programming
I'm pretty sure there used to be some sort of style guide in the wiki (the old wiki). But I cannot find any trace of it, so I possibly imagined it.
Anyway, does anyone have a style guide they could share, or point me to one in the wiki? I'm talking about things like camelCase vs snake_case, verbs start with capital letters etc etc.
Of course I could make my own rules, but I'd like to stay somewhat consistent with whatever other people are doing.
Thanks,
Jon
Dan Bron j@bron.us via forums.jsoftware.com / Mar 16, 2016 / to J
Pascal wrote:
> Anyway, does anyone have a style guide they could share, or point me to one in the wiki?
I can point you at:
http://code.jsoftware.com/wiki/PersonalTaste
and
http://code.jsoftware.com/wiki/User:Dan_Bron/Style
and
http://rosettacode.org/wiki/J/HouseStyle
But these were all created many years ago, and they’re all just initial braindumps: disorganized and far from comprehensive. They really never got past the “initial thoughts” phase (and mostly represent only my [Dan’s] initial thoughts, at that).
> Of course I could make my own rules, but I'd like to stay somewhat consistent with whatever other people are doing.
I can tell you my personal guidelines, which are broadly consistent with what I see on the Forums and other places I find code in the wild:
> I'm talking about things like camelCase vs snake_case, verbs start with capital letters etc etc. + Capitalization is primarily used to distinguish the parts of speech with visual hints: - Global nouns (particularly constants) are UPPERCASE o As a subclass of global nouns, for members of enums (fixed set of enumerated values), I often use ENUMNAME_MEMBERNAME (i.e. with underscores) - Verbs, having primacy in J and being the most common wordclass, are lowercase, or, when called for, camelCase with an initial lowercase letter. - Adverbs and conjunctions, being the remaining and least common wordclass, get the remaining distinguishable case: InitialUppercase (again, with CamelCase as needed) - I tend to aim for purely tacit formulations, where I can get them, so I don’t use explicit code as much, but when I do, local nouns are simply lowercase.
Other considerations:
+ Code layout: - When writing large tacit verbs, I try to break them up into functional, digestible pieces (which individually are easy to analyze on sight, or with less than 2 minutes of review). - This is made possible by J’s assumption that of as-yet-undefined names are verbs (which is a strong clue that that’s how J, i.e. Ken, expected you to do it). - I lay these pieces out in my script with indentation that reflects their calling tree, so that I can grok the high-level verb first, refining my understanding of the details as I progress down the script. - Another benefit is, at any given level, the implementation details of that level are indented to the right, so if I’m not interested in those yet, I can simply scan down the file to the next entry at the same indentation level. - Typically, these intermediate names are ephemeral, meaning they are never called outside the scope of the enclosing function, so I assign them locally. - At the bottom/end of the top-level definition, I assign theVerb =: theVerb f. to remove the dependency on these intermediate, ephemeral names (otherwise, you’d get value errors invoking theVerb, because the definitions of its components would have gone out of scope). + Indentation - I indent tacit definitions with two space characters (32{a.), because it keeps the “paragraph” defining the top-level function compact and easy to distinguish as an atomic grouping. Also because tacit code, even when modularized, can lead to some very long lines already. - I indent explicit definitions with a single tab character (9{a.) because I find anything narrower makes it hard to pick out the lone ) which terminates that specific definition. o One quibble I’ve always had with the Project Manager is that when it coalesces scripts, it removes this indentation, and so it makes it really hard to identify where one explicit definition ends and another begins, an issue exacerbated when the ultimate script has many sequential explicit definitions. + Naming - Is the hardest problem in computer science. I’d prefer a job doing cache invalidation any day. - That said, (J) verbs tend to be (English) verbs, (J) nouns tend to be (English) nouns, and operators tend to be ad-hoc (i.e. I have no rules yet). + Data - Inline (noun defines) to permit, to the extent possible, data-driven or table-driven code, with the minimum of overhead or redundancy. Data speaks for itself, and to the extent you can allow it to speak for your code, the better. - Sometimes a (noun define) at the bottom that either uses 0!:2 or a bunch of asserts as a kind of informal test script (turned off by default, but when turned on, tests correctness when the script is load’ed) + Comments - Large comment at the top of the script, laying out its purposes, usage, and caveats. - I also tend to make mention of any limitations imposed by the language/notation/implementation proper, so if/when the language evolves, I’ll be able to refactor or simplify my definitions accordingly. - About a paragraph of comments above every public (exported) name. Again, a sentence or two on motivations / purposes, and then examples of expected inputs and outputs, and caveats if any. I used to prefix executable examples with NB. EG: but I didn’t keep up the habit. - Large (noun define) at the bottom of the script walking through concrete examples (simulating or literal copy/paste of a live J session)
Here’s an example of my indentation style and preference for data- or table-driven logic, from something I knocked together for a poster on the J forums in 2013 [1]: NB. Scoring tables 'GROUPS POINTS' =. <"_1 |: ".;._2 noun define
5 ; 3 2 1 NB. 5 <= #riders <= 10 11 ; 7 5 4 3 2 1 NB. 11 <= #riders <= 20 21 ; 8 6 5 4 3 2 1 NB. 21 <= #riders <= 49 50 ; 10 8 7 6 5 4 3 2 1 NB. 50 or more #riders
)
NB. Logic report =: tally/@:|:@:record
tally =. ~.@[ sortStich catSumCount@;/. sortStich =. ,. /: ] catSumCount =. +/ (category ; ;) # category =. 4 <. 1 + 35 30 20 I. (* 2&<:) record =. [: ; (,: <"0@scores)~/&.|:&.>@:races scores =. [: score 0 ". ;:^:_1 score =. scorePlace pointGroup scorePlace =. (0,]) {~ [ * (<: #) pointGroup =. (0;POINTS) {::~ (<:;GROUPS) I. # races =. [: cutRaces LF , toJ@fread@jpath Pf cutRaces =. <@:cutFields;.1~ (LF,'--') E. ] cutFields=. 0 1 }. RE (rxmatches rxfrom ])Pf ]
You’ll need the complete script, from [2], to actually get it to run. There are more scripts in my SVN repository — of, I must warn you, wildly varying and inconsistent quality — illustrating the other considerations I’ve discussed here, in particular heavy commenting, automated testing, (noun defines), etc.
-Dan
[1] Scoring a road race in J, from “my program looks terrible” in Oct 2013:
http://www.jsoftware.com/pipermail/chat/2013-October/005364.html
[2] The complete script which will allow you to run the above code, scoreRoadRace.ijs:
http://jsoftware.com/svn/DanBron/trunk/uncategorized/scoreRoadRace.ijs
This script illustrates some, but not all, of the conventions I’ve expounded on here. If you remove the /uncategorized/scoreRoadRace.ijs suffix from the URL, you will be able to browse my larger code base. Most of the more mature scripts are in /environment, /general, and /uncategorized, but there’s really no good way to tell what type of quality you’re dealing with just from the filenames, you’ll just have to poke around.
Joe Bogner joebogner@gmail.com via forums.jsoftware.com / Mar 16, 2016 / to Programming
Dan, thank you very much for sharing. This style feels familiar after I've spent some time in the addons. I figure addon authors aren't held to a particular style, but it is certainly helpful to see it itemized and seems to be consistent with what I've seen elsewhere in J code.
Thanks again
'Jon Hough' via Programming programming@jsoftware.com / Mar 16, 2016 / to Programming
Yes, thanks Dan, this is pretty much what I was looking for.
Thanks,
Jon
Learning and Teaching J
The following is from Hacker News:
Delphi – why won't it die?
Delphi – why won't it die? (2013) (stevepeacocke.blogspot.com) 163 points by wx196 976 days ago | hide | past | web | 162 comments | favorite
Joeri 975 days ago [-]
My employer has a multi-million line codebase in Delphi which is still under active development. I mostly do web development, but every once in a while I go back in to build a feature on the Delphi side of the fence. The IDE itself is dated and no longer competitive with the best of the modern IDE's. The language and API however is updated and productive. You just need to get over Pascal-style syntax instead of C-style, and you are just as productive in it as if you were using C#.
Why is delphi still hanging on?
1. It delivers executables that need no dependencies. No VM's, no runtimes, no add-on dll's. Underneath it only needs x86 and win32 (unless you're building for mac, android or iOS, which it also supports). I wouldn't be surprised if our software still ran on windows 2000. Since the code is native, performance is never a problem even with wildly inefficient code.
2. It lets you build GUI software really quickly. Productivity in delphi for someone used to it matches any "modern" GUI development platform. Sure, the IDE misses a few features that competing IDE's have, but on the plus side it compiles ridiculously fast (a full build of 2 million lines takes less than a minute on a single core).
3. Delphi is the easiest platform by far to have legacy code on, because the maintenance cost is very low. Delphi's contemporaries (classic VB, MFC) have all gone through major upheavals. Delphi has managed to modernize the API's without breaking legacy code too badly (they even managed to elegantly retrofit unicode into the platform). This is why codebases that are based on Delphi somehow never get ported away from it.
Delphi's competitive with other desktop and mobile development platforms, even at what they're charging for it. What they're charging for it is the problem though. Only people already using delphi buy delphi, and so the perception is maintained that delphi is effectively dead, even when it isn't.
Svip 975 days ago [-]
I am not entirely convinced that unicode has been retrofitted elegantly into Delphi. A lot of legacy functions using string (read: what is now AnsiString) have been modified to still support string; so AnsiPos() for instance takes string, unless you use AnsiStrings unit. And that's just confusing.
In a code base like the one I work with all the way back to Delphi 3, there are other legacy issues as well; such as the late arrival of TBytes, which meant that in olden days you had to handle binary data in strings. Now suddenly they are unicode strings are far less reliable for unicode.
Of course, the compiler doesn't warn you about that, because it isn't clear what you were doing back then. Still, took us a year to get our code from Delphi 2007 to XE3. I am not saying Delphi is the worst thing ever, but I wouldn't say its legacy support is as elegant as you put it. There are issues, that are not noted by the compiler (unlike the deprecated flag for old functions and the like).
Also the fact that it used to have both {$ENDIF} and {$IFEND} is amusing, but at least now they only want one; but you cannot change it because then it would break code that needs to be compiled in an older version of Delphi.
Edit: But I will say this: I do believe unicode was introduced into Delphi as elegantly as possible. It's very hard to do truly elegantly, I'd imagine.
Joeri 975 days ago [-]
Well, when I say that they retrofitted unicode elegantly, I'm ofcourse comparing it to how unicode was retrofitted into PHP. Elegant is in the eye of the beholder I suppose. The same goes for maintainability. Upgrading the codebase was a sizeable effort for sure, but in my view it was less than it would have been had it been developed on another platform.
mappu 975 days ago [-]
Unicode was retrofitted into PHP and then the entire effort was abandoned, so yes, i think anything would be more elegant.
PHP currently supports unicode in the same way as lua or C - every string is a binary string. If you want correct UTF-8 behaviour in string functions then instead of using libc or string_ functions, you must pass the character set as an additional parameter to specialised mb_ string functions instead.
waps 975 days ago [-]
Even C++ compilers (except gcc) mostly compile themselves in under 30 seconds. How is that impressive ?
Delphi compiles source code almost as fast as it can read it from disk. Megabytes of sourcecode per second on a 486.
x0x0 975 days ago [-]
After building gui apps in c++/mfc, I tried delphi. It was amazingly productive. The closest thing I can compare it to is going from java/tomcat to rails; that feeling of getting so much actual work done is what makes delphi (and rails) stick.
huhtenberg 975 days ago [-]
> it compiles ridiculously fast
Courtesy of its simple precedence grammar ... as we all undoubtedly remember ;)
lobster_johnson 974 days ago [-]
Actually, Delphi/ObjectPascal's compilation speed comes mainly from being a one-pass compiler. Code is translated directly to native code per compilation unit, and since there is no "header file hell", each unit is an independent part whose generated code can be cached in its entirety, so during a single compile, if you have changed just one unit, the compiler only needs to compile that unit (plus dependencies) and then perform linking. The linking is much less complicated, too. Delphi also benefits from having a hand-coded parser and not too many machine code optimizations. I think the simplicity of the grammar may contribute some, but probably very little.
mistermann 976 days ago [-]
Software has got to be one of the most interesting industries, where among genuinely skilled people you can have such shockingly divergent opinions on really quite simple questions. From the article:
> Being highly productive has seen single Delphi developers produce software that would otherwise require a team of 5 developers. I’ve been in a team of 3 developers that out programmed a corporate wide application by having it up and running in a few months compared to another team I know of over 30 Java developers who 18 months later still had not produced their application.
I believe this to be completely true. At least for boring internal enterprise apps within corporations, the new languages/platforms and especially modern program design paradigms with their multiple tiers & supporting libraries, multiple levels of indirection resulting in 30 level deep call stacks, etc results in productivity perhaps 1/4 of what you could achieve with a product like Delphi.
Now this is just my opinion, and it is shared by many others, but there are even more who would vehemently disagree. Yet this isn't some "eternal mystery" class of a disagreement, for the type of application that Delphi is appropriate (very important), it can be very easily demonstrated if it is or is not more productive for the task at hand - the differences are so stark that the conclusion is undeniable. Yet, if you were to propose Delphi as a development platform, it would in most cases be career suicide.
I would suggest some of the main reasons for this are:
- as a developer, choosing Delphi is virtually career (skillset) suicide - it lacks much of the more modern "cool" language features developers so love to play with - (as a result) choosing Delphi as a platform is risky due to the small and shrinking developer base
jarrett 975 days ago [-]
> for the type of application that Delphi is appropriate
What type of application is that, in your opinion? Would you use it for a web-based app? (Many boring corporate apps are now web-based, and not just because the developers want that. The business people often want it too.)
> new languages/platforms and especially modern program design paradigms with their multiple tiers & supporting libraries, multiple levels of indirection resulting in 30 level deep call stacks, etc results in productivity
perhaps 1/4 of what you could achieve with a product like Delphi.
Modern languages don't particularly encourage or discourage that style of programming. Let's assume we're comparing Delphi to Ruby and Python as the modern competitors for the high-productivity, just-get-it-done language. Those languages have standard libraries with rather minimalist APIs, so I don't see the bloat there. N ow, it's true that frameworks in those languages, like Django and Rails, and huge and have deep callstacks and lots of indirection. But those frameworks are big because their problem domain (dynamic web app development) is so big and complex. I challenge anyone to find a framework in any language that 1) is as powerful and flexible as Django or Rails, 2) is sanely coded, and 3) doesn't have deep call stacks or lots of indirection.
Maybe I'm way off base, and you're not talking about web development at all. I went that direction because web development is what I think of when people start talking about boring business apps.
lobster_johnson 974 days ago [-]> What type of application is that, in your opinion? Not the OP, but I wanted to chime in that I think Delphi's forte is, was and will always be desktop-based GUI apps. That was always the main point. Admittedly, I haven't touched it since the early 2000s, but I can't imagine that it could compete as a language/platform for anything else these days. Its power comes from the tight GUI design/language integration, the brilliance of which is still unmatched by tools like Interface Builer; but the language — even with features like generics — hasn't been able to keep up. That said, in the late 1990s/early 2000s, I was actually using Delphi for headless backend apps. They were distributed, fairly complex backends connected using DCOM and interfacing with Windows technologies like TAPI and MAPI. We had to integrate with C libraries (linked as DLLs) and had to convert the header files to ObjectPascal. I actually wrote a tool called htrans that had a hand-coded C/C++ parser that produced very good ObjectPascal translations, but it was still a chore. Talk about going against the grain. In hindsight, I should probably have been using C++, and a lot of the problems our team had was due to the fact that we were trying to use Delphi for something that Borland just wasn't focusing on. But we did love the fast develop/compile/run cycle that Delphi provided, Delphi's OO was great at the time, and the apps worked. The difference between Delphi and C++ back then felt a lot like Rails versus, say, J2EE. It was incredibly easy to develop stuff.
waps 975 days ago [-]
> What type of application is that, in your opinion? Would you use it for a web-based app? (Many boring corporate apps are now web-based, and not just because the developers want that. The business people often want it too.)
I think this is mostly a lament of how very, very, very horrible web-based apps are for the developer. Delphi gets you pixel-perfect interfaces that work on a 486 with windows 95 right up to todays windows 8 (there is a version of delphi that would get you 3.1 support as well). With one recompile, the same app runs on android, ios. I have trouble writing a web-app that supports 2 browsers (and especially have not found a way to test that this is so without manually going through the app), yet every delphi app supports over 8 runtime environments.
> Modern languages don't particularly encourage or discourage that style of programming. Let's assume we're comparing Delphi to Ruby and Python as the modern competitors for the high-productivity, just-get-it-done language. Those languages have standard libraries with rather minimalist APIs, so I don't see the bloat there.
On the web there just isn't any other way of doing things. This is supposed to be flexible and "good" design, but here's the catch : changing one tiny thing in the backend requires you to change (e.g. go from 1 to 2 phone numbers per customer) :
1) the backend itself
2) the business rules in the second tier
3) the RPC/REST/... interface to the second tier
4) any and all frontend code interacting with this data
In delphi, by contrast, you change the backend, and that's it. At runtime, mind you, you don't even need a recompile in most cases. Tables will automatically start showing it, forms will magically contain the new field. > I agree...this is not forced on us by modern languages, it is current culture/fashion. There are so many cool geegaws out there today, it would be a shame to not use them such that you can include that experience on your resume (to hell with the additional costs and complexity, let someone else worry about that.)
I think part of the question being asked here is "how do these help application development" ? How do they improve the applications ? Well, they make them worse.
sehugg 976 days ago [-]
Look what Turbo Pascal/Delphi gave a PC developer in 1995:
- An insanely fast compiler
- Statically linked binaries -- no DLL hell (still important for certain kinds of applications)
- A proper module system, no need for precompiled header nonsense
- A UI framework/designer as easy to use as WinForms, at a time when the alternatives were MFC or Win32
- An easy upgrade path to 32-bit Windows
As long as you were ignorant of the world outside of a PC and Windows, it was nirvana.
vram22 975 days ago [-]
That lead architect was: http://en.wikipedia.org/wiki/Anders_Hejlsberg I read that he got $1 million (or more?) for leaving Borland for Microsoft. He's also worked on: http://en.wikipedia.org/wiki/TypeScript , Microsoft's enhanced version of JavaScript, which has been in the news somewhat lately.
Tloewald 975 days ago [-]
Micrsoft did far nastier things to Borland. E.g. During the Windows 95 preview stage they added code to the app launcher that would detect binaries compiled with Borland products and generate bogus errors. There's plenty not to forgive Microsoft for. It's just so much cuddlier mow that it's a little desperate.
visarga 975 days ago [-]
Borland Pascal 7 (running in MSDOS) had the best IDE I ever had. Debugging and editing was excellent. Ever since, I've been using prints and command line. :-( Why was there no linux port of BP7?
dsymonds 975 days ago [-]
Go's compilation speed is more than PR. It's reality when compared against what it is designed to replace. Believe me, there are several people on the Go team who fondly remember the "old" days of Turbo Pascal, for instance. But those tools just aren't around any more for practical purposes.
tiquorsj 976 days ago [-]
Delphi was one of the greatest development environment ever created when you just "needed to get shit done".
dpcan 976 days ago [-]
No question. I used Delphi 5 for a long time. The IDE was as easy as it gets, the sample code on the net was rampant, and it produced single little EXE files I could send to people and they had a full-on Windows application. The closest thing I've found since then that allows me to do something similar minus the IDE is BlitzMax, but the IDE was what made the process so silky smooth in Delphi, and I miss it.
tonetheman 976 days ago [-]
Yes yes yes. Delphi was amazing and still is really. I remember seeing it for the first time at a Borland conference and trying to explain what I saw to my team at the time. Just an amazing product. And super fast.
huherto 976 days ago [-]I think Delphi got right the "Visual Programming" paradigm. I am surprised that we don't have something similar on newer environments. Perhaps is that multi-user RDBMS with SQL and/or the Web broke the model. I don't know, but it is an interesting question.
vram22 975 days ago [-]
Also, Delphi didn't have a completely "Visual Programming" paradigm, if you mean it in the sense of some of those experimental tools that claim that all programming can be done visually/graphically, simply by drawing diagrams, dragging and dropping components onto a window, connecting them visually, etc. The visual part of programming with Delphi and similar tools like Visual Basic, was restricted mainly to designing/creating the UI, iteratively and visually, by dragging and dropping widgets like text boxes, labels, drop-down lists, gauges, graph controls, etc., onto a form (a window), setting those widgets' properties such as font, text foreground and background color, enabled/disabled, tab order, etc. etc. Also, data-aware widgets were useful; they would show the back-end database data represented by each widget, live, at UI design time (not just at run time). E.g. a grid widget could show the rows and fields of a table, live. But the rest of the code (widget event handling, business logic, etc.) still had to written in a text editor by the developer.
vram22 973 days ago [-]
>I found it a fast and easy tool for making and tweaking the UI. The IDE's integration of UI widgets and event-handling procedures was pretty slick too. Yes, you're right. I found it so too. I forgot to mention in my parent comment that Delphi also generated the stubs/skeletons for the event-handling procedures. Not only was that a convenience, it helped with learning the tool and Windows GUI programming too.
re1ser 976 days ago [-]
Delphi is a great RAD tool, but it's also slowly dying and has lower and lower market share, 100% of my income come from Delphi contracting at the moment, and I love Delphi, but its not a great choice if you're just starting your programming career and have to choose the language to go with. I've been sticking to Delphi for whole my programming career (3 years professionaly, 10+ years hobby programming, i'm 24 now), but its more and more occuring to me that I have to learn some new tech ASAP if I want to progress further. Delphi has no proper crossplatform support and it's a big minus. Also it has ridiculous price.
swinnipeg 976 days ago [-]
Was once in a similar situation myself. One path is to identify a future customer pain point that will occur if they continue to use Delphi. You can direct the solution to a language/platform you wish to learn, and work like a dog to develop the new skills and build a great piece of software in this new language.
re1ser 976 days ago [-]
Thats exactly my plan, to learn some basics then further improve skills on minor contracting jobs I get and I feel comfortable to do them in new language. It would probably be C++.
blub 975 days ago [-]
If you're looking at C++ already then I'd recommend Qt. I think it's pretty close to the RAD feeling I remember from C++ Builder and by extension I assume Delphi.
Compared to them it's not strong on data components that allow you to connect a DB to a UI, you will have to write SQL and code for that. But it is a joy to use, cross-platform and at least on the desktop it is free to use if you don't mind LGPL and shipping DLLs/so with your app.
Udo 976 days ago [-]
I spent the first years of my non-school life developing things in Delphi, including CGI binaries in the end. I can't say how much I loved the language and the IDE. In fact, XCode is still somehow trying but falling far short of providing the same amenities for developers (maybe on purpose).
Since I rediscovered dynamic languages in the early 2000s and haven't (except for some experiments in C) looked back.
It's funny how you can selectively remember the good aspects of a language and forget how much better life has become since you dumped it. Out of nostalgia I checked out Lazarus and I'm glad it has a somewhat thriving community. However, for me it was clear immediately that the time of Delphi/Pascal has passed for good.
spitfire 975 days ago [-]
Delphi/Pascal and Wolfram mathematica are the two things I point people to when we talk about documentation.
Every single function had a working snippet example. Mathematica had details and applications for each function, while Delphi/BP had a well written explanation of what the function would do and how to use it. They are the standards that have not been surpassed yet. Or even approached imho.
These days you get an auto generated docstring explaining that xval is "the x value passed to the function".
Things of Interest
Here are some topics of interest.
The Great AI Awakening
This article from the NY Times tells "How Google used artificial intelligence to transform Google Translate, one of its more popular services — and how machine learning is poised to reinvent computing itself".
File:The Great AI Awakening.pdf
Building Jarvis
This is an account by Mark Zuckerberg about building a simple AI to run his home.
File:Mark Zuckerberg builds an AI.pdf
Skills Gap and What to do About it
What are the biggest skill gaps among technical roles?
We’ve been fielding a lot of questions from our users on what skills are in highest demand. Luckily, we’re not short on data. So, we decided to explore the topic in more depth. Before we dig into our findings, we’ll tell you how we got there. We based our research on approximately 500,000 resumes and over 13,000 open job descriptions with the goal of analyzing the top "skill gaps" among technical roles. To offer more clarity, we recognize “skill gaps” as skill keywords that appear proportionally more frequently in job descriptions than in candidate resumes. The data was scaled across 2,500 keys to identify the skills with the biggest differences between demand (jobs) and supply (resumes).
Okay, really, what is the trend?
Demand for skills associated with NoSQL technologies has clearly outpaced supply. "NoSQL,” "Redis," "Hadoop," "Cassandra," and "MongoDB" were among the top 15 scarcest skills. Interestingly, relational database SQL technologies such as “Oracle,” “MySQL,” and “SQL Server” are at a slight surplus. For example, we’re seeing skills like “MySQL” appear more frequently in resumes than in actual job descriptions. Intuitively, this may not come as a huge surprise: as companies are collecting more and more data, it’s likely many are switching to newer database technologies over relational database systems. They will need employees who can manage these systems. Times are changing - and quickly! As Business Insider tells us, digital data is growing at an exponential rate, doubling every two years. Thus, there's also a major skill gap in the data science and analytics fields - where the objective is to make sense out of all this data. As data science becomes integral to all industries, we expect all departments within all companies to start requiring skills like "Machine Learning," "Data Science," "Statistical Modeling," and "Data Mining." We’re already seeing the trend...
As candidates, how do we keep up? 1. Degrees and Bootcamps: An increasing number of universities are offering degrees and specializations that focus on the relatively nascent field of data science and analytics. For programs with shorter commitments, data bootcamps are a great way to get a solid foundation and practical experience in data science. We recommend: • Metis: Data Science Bootcamp • General Assembly: Data Science • Top 5 Data Science Masters Programs 2. Online Courses: MOOC's (Massive Open Online Courses) are becoming popular. There's no shortage of courses focusing on topics such as big data, data mining, and machine learning. We recommend: • Coursera: Introduction to Data Science • Udacity: Intro to Hadoop and MapReduce • edX: Data Science and Machine Learning Essentials 3. Just Do It: If you already have some technical background, the best way to learn is to get your hands dirty. There are plenty of open data sources and packages with thorough documentation out there to get you started. Whether it’s forecasting real estate prices or building a recommendation engine for movies, choose a project that interests you. We recommend: • Kaggle Competitions • Google's Public Data Directory • UC Irvine Machine Learning Repository
Sign up for the UpScored platform here to see how your skills match up to top jobs in NYC.
- Elise & Dan , CEO & CTO, respectively