Long rant about "obsolete" languages (not); contains swearing
Inspired by @uncanny_kate’s discussion, I thought it was about time to rant about one phenomenon:
People shitting on “old” or “legacy” languages. It’s a long subject and I’d probably get close to the 65K limit my instance provides (nobody wants to read 65K chars anyway) so in the replies to this I’ll describe each such language that I’ve gotten hate for. I’ll try to make them as self contained as possible.
Long rant about "obsolete" languages (not); contains swearing
Number two: #pascal (and #delphi). Going raw on this one.
“Pascal is just for teaching”. As if a language that’s easy to learn for beginners is bad. #python and #js are used a lot in teaching too and I don’t see them get shit for this. I pity people who start with #c because that’s an unreadable mess. Additionally, it came I think 2 years earlier than C, so it had to deal with the same constraints that C had. It has a lot of low level capabilities and plenty of compiler directives to choose from in case you’re a control freak. We even have asm
blocks which, unlike C, aren’t (excuse my Spanish) dogshit to use, we can just reference variables inside them and it works as expected (you have to do some weird stuff in C to get that). We have pointers too and use them decently frequently. Pascal, along with ALGOL-60, was designed as a language for formal specification and teaching of algorithms, but contrary to ALGOL-68, emphasis was put on simplicity (imagine a world in which ALGOL-W was ALGOL-68…).
“Pascal is slow”. What? Pascal was fast even back when Turbo Pascal was all the rage, a direct competitor to C. #apple sure had their reasons to choose Object Pascal (basis for Delphi) when they did the Apple ][ and Apple ///). There also existed UCSD Pascal which ran on the UCSD p-System, popular at that time (it ran actual Pascal p-code, which means it was the Pascal equivalent of the #lisp Machine, really powerful). Free Pascal is on par sometimes with even GCC.
“Pascal is outdated”. News flash for people who’ve only tried Turbo Pascal: we have interfaces, generics, lambdas, Unicode support, database support through a common interface, dynamic arrays, abstract and sealed classes, for..in, operator overloading, static methods/properties, RTTI, type inference and so, so, so much more. We’re more than able to meet modern demands with the amount of libraries at our disposal. It runs on more platforms than it ever has before (I beg you to find me a more portable language than Pascal (and Free Pascal specifically) that’s not C, it’s gonna be a rough realization). I have actual enums that work like symbols, I can have negative indices, character indices, enum indices, whatever. That allows me a lot of freedom (for example, it’s a pain to iterate over enums in C, something I have to deal with in #cpp in my compiler). It’s fast, performant, easy to understand and still has room for improvement.
“Pascal’s syntax is too verbose”. It is verbose in a readable way, unlike some other public, static and void of any elegance main languages that are both terse and verbose in the most cursed way. The syntax is well structured and strict, which is good for not just beginners, but also parsers. In C, a function is 1. its signature and 2. the declaration of variables.. and definition of function which may be mixed up. In Pascal, it’s clear: 1. function/procedure signature, 2. declaration of variables, 3. definition of function/procedure/program. Simple as that, it follows a predictable structure. Don’t even get me started on C’s =
vs ==
(which can BOTH be used as valid Boolean expressions), unlike Pascal where we have :=
for assignment and =
for comparison (they’re mutually exclusive, as in assignment isn’t Boolean and comparison isn’t an assignment). We also have <>
which is really different from !=
in C. I don’t need to insert break
everywhere in my Case … Of section in Pascal because the syntax is strict and so it knows where to stop. There’s a strict difference between a pointer and a string (we have native strings too, btw, unlike C). We also have native set operators (and sets, obviously); we can check if an element is in a set via in
, we can include
/exclude
elements, compare sets ((symmetric) difference), combine and intersect them). This is all in the language, no extra units needed.
You Pascal and Delphi haters (usually ones that never even attempted to try these languages, as always, the grapes sure are sour) aren’t grateful enough for these languages existing. For one, it’s the first widely used implementation of a bytecode (if you want to put it that way, it’s also the first VM). The chief designer of Delphi went on to create C# (which you don’t seem to have a problem with, mostly, although the Delphi influence is clear as the night sky in the mountains). Also, have you heard of these irrelevant programs named Skype and InnoSetup? Yeah, those ones. News flash: they’re in Pascal (I think Delphi specifically). Delphi essentially pioneered the concept of RAD (rapid application development) in an IDE form which is why it evolved to fit so nicely with GUI development in mind, unlike its C++ sibling in RAD Studio. It’s still hard to beat Delphi in the GUI department (too bad Embarcadero realized a bit too late that they needed a Community Edition… or Linux support). Visual Basic, Visual FoxPro, VB.NET, C#… it all started with Delphi.
Long rant about "obsolete" languages (not); contains swearing
Number four: #tcl #tcltk. Not as much hate as Perl gets, but a lot of misconceptions that I want to clear up for people who might hear about this for the first time:
Tcl != Tk. Although they’re released together nowadays, Tk is a standalone cross-platform widget toolkit. That’s where the Tk in Tkinter comes from. There are several bindings for Tk: Ada (TASH), Python (the aforementioned Tkinter), Perl (Tcl::Tk, Tkx and Perl/Tk if you want native Perl access to Tk structures), Lua (tclua and ltcltk), Haskell (HTk), Ruby, Scheme, Ksh (through dtksh), R (tcltk) and probably many others. The Python bindings even use Tcl as a bridge to Tk, same with Tcl::Tk and Tkx from Perl).
“Tk looks bad”. While it used to look like Motif on Unices, now it has (for quite some time) a native look and feel + theming support. Tkinter people sure don’t complain and probably neither do you realistically speaking.
“Tcl is a toy language”. On the contrary, it’s really powerful with the syntax it has (that and its syntax is defined by the Dekalogue, only 12 rules). In a way, it’s like Lisp and Forth (two of my crushes). I even tried a Forth-esque DSL in Tcl… and I could actually do it. I can implement if I wish try/catch, for..in, exceptions, classes, I can model it to my liking. This argument is genuinely more petty than even “Lisp has too many parentheses”. Additionally, it isn’t complex, which is a good thing (you can actually understand the whole language, implementation included). You can even redefine anything in Tcl using rename
or have access to the Tcl interpreter using eval
, uplevel
and upvar
for some metaprogramming if you so wish.
“Tcl has no types”. Yes, if you want to be strict about it, it only has strings (although that’s like saying that Lisp only has lists). You don’t need to perform conversions, however you aren’t likely to introduce bugs because the checks on the format of the strings are very strict. It’s a bit like Postel’s law: “be conservative in what you send, be liberal in what you accept”, but in reverse I think. Even better, you don’t need serialization because everything is a string already. You can even do stuff like sending a list through a TCP socket through puts $socket $mylist
and on the other side set mylist [read $socket]
, it’s that easy. The central data structure is the list, not the string, and any Lisp programmers knows the implications of that.
“Tcl is slow”. This shares the same sentiment as in the Perl argument. Of course it isn’t gonna be a power house for sure in the runtime department, but it sure is quick to develop in. Heck, once you have some commands going on, you can start writing executable files that look like configuration (if you really tried, you could surely replicate #nginx syntax for example).
Besides that, there are a couple of other nice things about Tcl:
lmap i {1 2 3 4 5} { expr $i*$i}
which prints 1 4 9 16 25.I stopped using TCL/wish in about 2004 - this was a BIG
mistake - I can now build GUIs in described by pure text.
Nothing is hidden it’s all text - I just need emacs and make.
Why oh why did I ever even click on a button to start Xcode”
The only people that are mad about Tcl/Tk at this point are RMS (because he’s still butthurt that #guile failed in face of Tcl and not even Emacs adopted, only Guix (Guile is good though), he even went so far as to call John Ousterhout a “parasite” (ironic coming from him, huh?)), MAYBE Larry Wall and people who didn’t bother checking up Tk (or looking at Tcl ever). And with that (for today, I think) I am done, although I could touch up on #forth, #php, #ada, #cobol, #smalltalk, #fortran… Even #ml #prolog. These languages deserve some love too, even though they aren’t particularly used. I truly believe that Tcl should become a more popular language, for me it was love at first sight (I like it so much that this is the language I chose to implement for my bachelor’s thesis on a Raspberry Pi Pico). Long live Tcl.
re: Long rant about "obsolete" languages (not); contains swearing
re: Long rant about "obsolete" languages (not); contains swearing
@errante Tcl is unashamed in its DSL capabilities (Lisp is too, Forth is the crown jewel imo). When you don’t have a lot of syntax, it’s really malleable. I personally love this aspect of Tcl (because of Perl and Forth surprisingly, Lisp somehow doesn’t have the same feeling (Racket kinda does, you can do whatever language you want)).
re: Long rant about "obsolete" languages (not); contains swearing
re: Long rant about "obsolete" languages (not); contains swearing
@errante I’ll still call it a DSL, especially after having tried it for 2-3 weeks straight to get my feet wet. It’s on the same level as saying “Tcl is just a bunch of strings that so happen to be keywords”
re: Long rant about "obsolete" languages (not); contains swearing
re: Long rant about "obsolete" languages (not); contains swearing
@errante maybe we have different perspectives on what a DSL is (or should be, rather)
re: Long rant about "obsolete" languages (not); contains swearing
re: Long rant about "obsolete" languages (not); contains swearing
@errante honestly, this happens even if we’re not talking about DSLs, but just generally learning a programming language. Some languages (C++, Rust, I’d say Python to an extent) like to solve problems by syntax, others (Go, C by… actually solving them with the tools available. The latter group doesn’t change a whole lot while the former one has “hip” and “fresh” new “features” added.
Basically, don’t be a kitchen sink.
re: Long rant about "obsolete" languages (not); contains swearing
Long rant about "obsolete" languages (not); contains swearing
@alecui gosh. I had forgotten TCL existed
Long rant about "obsolete" languages (not); contains swearing
@tiphphin wait until you see what it can do ;)
Long rant about "obsolete" languages (not); contains swearing
@alecui gitk is written in TCL, isn't it?
Long rant about "obsolete" languages (not); contains swearing
@tiphphin yep, almost (if not) everything involving Tk also involves Tcl at some point
Long rant about "obsolete" languages (not); contains swearing
@alecui oh 🤦♂️. Gi tk... Obvious when you think about it. 😂
Long rant about "obsolete" languages (not); contains swearing
@alecui Lisp has had a compiler since before Lisp 1.0; it had a compiler BEFORE it had an interpreter (and before it had a REPL, which needed the interpreter).
The original notation for Lisp ('MEXPR', meta-exoression) did not use (many) parentheses; the SEXPR notation we now use was developed as a convenience, but before the release of Lisp 1.0 in the spring of 1960.
https://www.softwarepreservation.org/projects/LISP/MIT/AIM-001.pdf
Long rant about "obsolete" languages (not); contains swearing
@simon_brooke Do you think Lisp haters know that? But thanks for the link regardless. I am glad Lisp doesn’t have m-exprs now and history left that syntax to Wolfram language.
Long rant about "obsolete" languages (not); contains swearing
@alecui I implemented MEXPRS in Beowulf, but mainly for the shits and giggles.
Long rant about "obsolete" languages (not); contains swearing
@simon_brooke I’ll give you credit, you’re the first person I’ve seen attempt to use Lisp 1.5 seriously, is the parsing easier or harder than for s-exprs?
Long rant about "obsolete" languages (not); contains swearing
@alecui OK, so I wrote the MEXPR parser in instaparse, which is an absolutely beautiful parser generator, so it was really quite easy. It has the benefit that I was able to copy the MEXPR text from the #Lisp 1.5 Programmer's Manual straight into the REPL.
I agree there's no practical point in doing this; it was just for fun.
https://github.com/simon-brooke/beowulf/blob/master/src/beowulf/reader/parser.clj
Long rant about "obsolete" languages (not); contains swearing
@simon_brooke unrelated: I love how the first photo on your README makes a lambda, nice accidental touch
Long rant about "obsolete" languages (not); contains swearing
@alecui Aye, I wrote trace functions quite early in debugging the interpreter, and when I first traced RANGE and saw that screen emerge, is was just a surprising moment!
So obviously that had to become the logo for the project ;-)
Long rant about "obsolete" languages (not); contains swearing
@simon_brooke what improvements do you want to make in the future to this project? What are your TODOs and TBDs?
Long rant about "obsolete" languages (not); contains swearing
@alecui OK, well, at present it's on hiatus. I ran into a bug where Clojure's lazy evaluation was causing the interpreter to fail; and although that's almost certainly trivial I didn't track it down. Most of the thing works, but I'm not a great completer-finisher.
I've started work on re-implementing it in C, to compile down to ARM code, in order that it could run on a Raspberry Pi Pico; but I haven't (yet) got very far with that.
Long rant about "obsolete" languages (not); contains swearing
@simon_brooke you can always choose C++ and make it slightly less painful… Or uLisp. :)
Long rant about "obsolete" languages (not); contains swearing
@alecui I personally find C++ a lot harder to get my head around than C. BCPL was one of the first 'high' level languages I learned (because the runtime for Cambridge Lisp, a variant of Portable Standard Lisp, was written in BCPL) and consequently I tend to use C as a sort of glorified macro-assembler!
Long rant about "obsolete" languages (not); contains swearing
@alecui Getting the line editor in the REPL working fully would have been the next goal, but really the big one is compilation, and I don't really want to compile down to JVM, because I don't find it a congenial target.
The `develop` branch is quite a lot ahead of `master`, but as I say it has a flaky lazy-sequence bug that I haven't fixed.
Long rant about "obsolete" languages (not); contains swearing
@alecui
counter-argument: Lisp as a language is identified by its readily identifiable community
https://www.nhplace.com/kent/PS/Lambda.html
Also
(loop (print (eval (read)))) ; in lisp pseudocode
In what way is this pseudocode? ;p
Long rant about "obsolete" languages (not); contains swearing
@roboneko @icedquinn @screwtape wait until you find out about Forth
@alecui @roboneko @icedquinn
, as a domain specific language in lisp https://letoverlambda.com/ !
@screwtape @roboneko @icedquinn I have no idea how I managed to skip that part when I was reading LoL
@alecui @roboneko @icedquinn
iirc the book kinda goes from
"what if we use unhygeinic macros to create a pandoric let over indirective lambda
to
by the way, eat your heart out lisp prolog implementors here's forth"
@screwtape @roboneko @icedquinn the McCarthy-Moore thesis
Long rant about "obsolete" languages (not); contains swearing
@screwtape it is pseudocode in the sense that in an actual Lisp implementation of this idea it’s a bit more nuanced than that.
Long rant about "obsolete" languages (not); contains swearing
@alecui Over 40 years even, for arrays. Interlisp 1974 had them.
There's also work for concurrent GCs being done.
Long rant about "obsolete" languages (not); contains swearing
@alecui I really enjoyed reading this. You hit the nail in my opinion. Thanks! 🚀
Long rant about "obsolete" languages (not); contains swearing
@alecui I just discovered VSI has Pascal for OpenVMS x86_64, so there must still be a userbase (cough..me cough) using it for them to port it. I have a soft spot for pascal
Long rant about "obsolete" languages (not); contains swearing
@praetor my soft spot for Pascal appeared when I tried it on DOS (Turbo + Delphi) and Amiga. Without Pascal I wouldn’t have tried Ada (I’m mad I can’t use it for my current project, but oh well…)
Long rant about "obsolete" languages (not); contains swearing
@alecui Are you an experienced Ada dev? Would love to hear a bit about how you percieve the language, what you are using it for and if you could recommend a good stack to learn it.
Long rant about "obsolete" languages (not); contains swearing
HUGE DISCLAIMER: this is all my personal experience of a huge noob, you’re better directly asking the #ada community.
I’m not experienced at all, I’d really want to get more involved. I am pissed off I can’t use Ada for my project because usb_embedded (a crate) is useless. Literally everything else around the Ada support for the Raspberry Pi Pico (https://pico-doc.synack.me/) is well supported but the most crucial part (getting input from USB) is totally borked. No examples to help me either, Synack had no clue either.
Also, I had a huge skill issue connecting ada_language_server (ALS) to Emacs (since ada-mode really, REALLY prefers eglot over lsp-mode, they even say it out loud:
”
ada-mode can be configured to work with a wisi parser, or an LSP language server via eglot. It can also be configured to experiment with other backends, such as tree-sitter or lsp-mode, but these other backends are not yet fully supported.
The Language Server Protocol (LSP, https://langserver.org) defines an external language parser, and it is supported by the GNU ELPA package eglot, using an Ada language server provided by AdaCore (ada_language_server, https://github.com/AdaCore/ada_language_server/). LSP supports face, indent, and multi-file navigation. However, as of ada_language_server (als) version 23.0, als provides face and single line indent, but both have significant problems, so it is only useful for xref. “
).
For a noob’s first impression, the syntax is a bit convoluted and The_Capitalization_Style is… interesting, to say the least, but it grows on you, I got used relatively quick. If you get into Ada, just go and install GNAT Studio (unless you’re willing to fiddle around with your editor of choice). We also have Alire (Ada LIbrary REpository) which has a decent amount of useful crates. A really good choice for embedded and low-level, see AdaCore’s guides.
Oh, it also has a… dialect? supraset? called SPARK with pre- and post-conditions and you can use those to actually prove that your program works.
I would definitely choose it as a systems programming language, I’ll give it another shot, but not now.
@alecui Also FL Studio (ex Fruity Loops) still uses Delphi and lots of people love it
Long rant about "obsolete" languages (not); contains swearing
Number three: #lisp. This is spicy enough, so:
5*a+3
is(+ (* 5 a) 3)
. However, in spite of the fact that it may look initially a little funny to the unaccustomed, there are some sound technical reasons why Lisp syntax exists:5 * a + 3
is(+ (* 5 a) 3)
, while5 * (a + 3)
is(* 5 (+ a 3))
;Lisp is old. No? There are modern dialects of Lisp such as #Clojure, #Racket and the myriad of R{5,6,7}RS #scheme implementations. We’re still going strong, thank you. If anything else, #AutoCAD is still a thing and that has AutoLISP, so it definitely lives on.
Lisp is slow. I have actually heard this from a teacher live (along with the Lots of Irritating Small Parentheses stab). I asked them when was the last time they’ve tried Lisp. He tried it 30 years ago. Before doing his PhD in #Haskell 98 (which was fresh in #Romania, nobody has heard of it, I still have great respect for him). When all datatypes are appropriately declared, a typical commercial (and even some non-commercial) Lisp compilers produce native machine code on par with C++. It was true back when Lisp ran on the IBM 704 because they could barely handle the GC, but over times the compilers improved a lot. To equate 1960s (or even 1980s) Lisps to modern Lisp compilers is like claiming C is slow because the only time you’ve tried it is with a C compiler on the PDP-11.
Lisp is big. First of all, I find this really funny because Scheme (a branch of the Lisp family) is minimalist yet powerful in its nature. This myth started around the 1980s when Lisp was indeed big (because it packed a lot of useful functionality and there was a limit to how small that functionality could be made). Lisp vendors noticed that and nowadays Lisp is one of the few programming languages in recent years that has not been allowed to grow in size by leaps and bounds with every release. At this point, this point is (excuse my Chinese) fucking bullshit, people are happily running Electron-apps and they don’t care at all about resource usages because they’re all running the latest and greatest hardware anyway. Languages are getting more and more bloated (ahemc++ahem) and so Lisp actually ends up looking like a compact alternative.
Lisp has no arrays. This is also BS, we’ve had an array datatype for at least 30 years. Even though the Lis of Lisp is from, shocking, List, it doesn’t mean that it’s the only data type. Lisp offers powerful support for single and multi-dimensional arrays, arrays of varying element type, and array access that provides transparent access to fixed size arrays, arrays displaced to other arrays, and arrays whose size is expected to dynamically grow and shrink.
Lisp has no compiler. It… does? Since its earliest days Lisp implementations have been variously interpreted or compiled, and often both. Much important work in the theory of program compilation has been done using Lisp and so Lisp benefited from that. All modern Lisps have a compiler (and also a REPL which allows for interactive debugging, thank us for that and much more at the end of this post).
Lisp is not standard. Let me present ANSI X3.226/1994 (first ANSI standard for any OO language btw) and RnRS (5 <= n <= 7 nowadays). The Common Lisp HyperSpec (CLHS) is a webbed adaptation of the ANSI Common Lisp standard made by LispWorks, heavily cross-indexed with a lot of indices.
Lisp doesn’t talk to other programs… Um, most serious Lisp dialects and implementations definitely have FFI, most even have easy access to TCP, CORBA, COM, databases etc. This is a really weird point that I’ve actually heard, people think Lisp is isolated from everything.
Lisp haters should give Lisp more credit. It pioneered a lot of features that people take for granted such as REPLs (which are trivial in Lisp, literally
(loop (print (eval (read))))
(in Lisp-ish pseudocode), GC with mark-and-sweep, AST as a tree structure,if
(yes, not even FORTRAN had conditionals), a function type, recursion, programs composed of expressions, a symbol type, a notation for code using trees of symbols and constants, and the concept of having the whole language there all the time. What I mean by the last point is that there’s no real distinction between read-time, compile-time, and runtime. You can compile or run code while reading, read or run code while compiling, and read or compile code at runtime). This lets you reprogram Lisp’s syntax; running code at compile-time is the basis of macros; compiling at runtime is the basis of Lisp’s use as an extension language in programs like Emacs; and reading at runtime enables programs to communicate using s-expressions, an idea reinvented as XML.Lisp is pretty nifty after all, huh?