Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I don't have a background on theory of programming languages or history of CS (I'm EE), correct me if I'm wrong but:

1- I have never seen a language that made me wow. Like, to me, this whole concept of making a digital logic architecture do a task should be "solved" in a systematic/mathematical sense. Yet, whenever I read on criticisms of languages, people always talk about stuff like "Go doesn't have generators", "Rust macro is a mistake", "I don't like python's async story", "C's way of things is outdated" etc...

As an analogy, this whole discussion of PLs in CS circles is like complaining about whether we should use `dot` notation or `d/d(t)` notation or whether we should use `t` or `x` in solving a differential equation. Like, we are not solving the actual DE, but complaining about issues irrelevant to the big picture.

2- I have a feeling that https://www.red-lang.org/ is something completely new and innovative.

3- I think concepts like formal-proofs and RTOSes are under-rated.



About (1)

The first Prolog program I ran just blew my mind - sort of "But how did it do that!?" I understood what I wrote down, and how that explained the problem, but a mental model if how that was used by the runtime to solve the problem needed a while to develop.

Similarly Smalltalk was like: "Everything is an object?". I mean the language doesn't have an "if" statement! You send a code block as a message to a boolean value with an "ifTrue" method.

Not that I know these languages to any significant depth, just dabbling.

To me there are a few oddball languages that are simple, have one abstraction of abstraction and are quite weird, but have a stack record of "heroic deeds" by their practitioners.

I mean C#, Java, C, C++, Go are quite similar if you squint.

But Prolog, Forth, Smalltalk, J, Lisp, etc. are definitely something else that stretches your mind a bit in different directions.

And I think that this is a valid point.

It's worth spending a bit of time reading about and playing with these languages. Not because they are useful (although they might well be), but because they will give you a few different ways of thinking about problems that will extend your mental reach.


> Similarly Smalltalk was like: "Everything is an object?". I mean the language doesn't have an "if" statement! You send a code block as a message to a boolean value with an "ifTrue" method.

Incidentally, I don't think that this is how they got there, but this could have come from taking the lambda calculus extremely seriously: in the classical encoding, `true = fst` and `false = snd` (i.e., `true x y = x` and `false x y = y`; or, pointlessly, `true = const` and `false = true id`), so that `if` is just `id`, in the sense that `if true = true` (meaning `if true x y = true x y = x`) and `if false = false` (meaning `if false x y = false x y = y`).

https://en.wikipedia.org/wiki/Lambda_calculus#Logic_and_pred...


I came to this thread to write about prolog too. it wasn't the first program I wrote, but after a good introduction, then I started thinking the way prolog makes you think, I was blown away. I loved it and I hope I get to use it again!


I feel the same way about Snobol4. It gave me the same wow factor that Prolog did.


> 1- I have never seen a language that made me wow. Like, to me, this whole concept of making a digital logic architecture do a task should be "solved" in a systematic/mathematical sense. Yet, whenever I read on criticisms of languages, people always talk about stuff like "Go doesn't have generators", "Rust macro is a mistake", "I don't like python's async story", "C's way of things is outdated" etc...

Math does have a lot of notations that express the same, but are used for different purpose, where some of those are better suited for solving some task than others. One of the simpler examples is polar vs cartesian coordinates. Where polar coordinates is expressed by angels and distance from a zero point. While cartesian we use the distance on axis from the zero point. Both can express all the same points, but some problems are easier to solve in one of those and some are easier to solve in the other. Coordinate system is definitely not the only place where you have this in math, and it is probably one of the simplest examples.

So math, and all it's different ways of being expressed is more of an example why we need different languages, and that programming languages matter. Than a counterexample of why languages shouldn't matter, and that we are fine with any one language.


> Where polar coordinates is expressed by angels and distance from a zero point.

This is surely the only chance I'll ever have to say "non angeli, sed angli", and by God I'm going to use it.


Err, the angles of our better natures.


I agree with your statement that concepts like formal-proofs is underrated. Fortunately, one of the general trend that I'm seeing going forward is the birth of programming languages with more and more sophisticated type systems. In these languages type systems do not only capture object types (eg., int, string) but also various other aspects.

For example functional languages and their monadic construct supports capturing various interesting aspects. This allows for really useful feature such as capturing concurrency behaviour (Future/Promise) and possibility of returning errors (Try), at compile time.

Then there's Rust where memory ownership can be reasoned about at compile time.

Languages such as Idris allows to declare a type that is dependent on the value (eg., declare that this function "x() can only return odd numbers?)

I also happen to work in a company where we try to bring type-safety to the databse world with our product TypeDB.

I think this trend is very good to see - stronger type-system = safer code. In a way the stronger type system a programming language has, the more it can validate at compile time. And therefore, we can say that such language somewhat provides what formal proof / formal verification systems ought to provide, but in a practical setting.


Are you familiar with prolog ? For me it was kind of "wow" as it's very different from all other programming languages. I don't use it but it was very interesting to learn it.


The OP doesn't really touch on this aspect, but I think one of the most important traits of a PL is what it doesn't let you say (there's almost nothing that Lisp doesn't let you say, which is a double-edged sword)

A majority of Haskell's innovations have been in the space of placing interesting new kinds of constraints on code

Rust's big innovation is not allowing you to make memory errors (in designated sections of your code)

Go's headlining feature is not allowing people to write code that's extremely abstracted, which helps readability

And this isn't just for avoiding mistakes: code that's very regular can be more easily processed by a machine to make it more efficient

So looking at it through the lens of syntax is missing a lot of the picture. You're right that syntax is rarely important. At the end of the day the differences between code and notation are: 1) code often grows to enormous sizes where managing it becomes a challenge, and 2) code is processed by a machine


> Rust's big innovation is not allowing you to make memory errors (in designated sections of your code)

I’d actually say Rust’s ownership model is its defining feature and big innovation; memory safety without garbage collection was the original goal of the project, but that has arguably actually ended up being more of a side-effect of the ownership model than the actual artefact, from the innovations perspective. Several other languages have been adopting significant ideas from Rust’s ownership model without actually needing it for memory safety.

(Also, some factual clarifications on the wording you used: Rust doesn’t allow you to make memory errors except in areas marked with the “unsafe” keyword—you’re marking small dangerous zones, rather than marking safe zones. But scripting languages are normally memory-safe too, it’s the absence of any garbage collector that makes Rust special there.)


Either way the point stands: Rust’s biggest features are about what you can’t do, not what you can do


Absolutely.


I took a class simply named "Programming Languages" as part of my degree, and we focused on one different language each week for the entire semester.

The only two to make me go "wow" were Lisp and Haskell. They really are that strange and different.

(Well, technically the assembly language we used also made me go "wow," in the sense that I had sympathy for the suffering of programmers in the olden days, but as an EE you may have a different takeaway.)


> As an analogy, this whole discussion of PLs in CS circles is like complaining about whether we should use `dot` notation or `d/d(t)` notation or whether we should use `t` or `x` in solving a differential equation

Until you start manipulating the 'dt's on their own which wouldn't occur to you if you were using the dot notation.

(And then some people tell you that it's illegal, or maybe okay but only if you've taken real analysis... it gets confusing)


1. Read this: https://physicsworld.com/a/how-feynman-diagrams-transformed-...

Main point:

> Theory, Kaiser suggests, is ultimately less important to theorists than the tools that mediate their calculations.

To me, programming languages are almost like Feynman diagrams or chemical notation in that they define how we think or what we think is 'real' in programming. In that sense, we should absolutely care about the fine-grained characteristics of the tools. After all, doesn't a chef prefer a sharp knife to a blunt one?


(1) F# Type Providers still blow my mind.

Strongly typed SQL/XML/CSV/JSON without boilerplate is a massive leap forward, and it's a shame that it hasn't caught on.

https://fsprojects.github.io/SQLProvider/#Example


Scala experimented with type providers, but it looks abandoned: https://docs.scala-lang.org/overviews/macros/typeproviders.h...

Idris has them (but it's Idris) https://docs.idris-lang.org/en/latest/guides/type-providers-...

This SO answer states that Java has something similar called "Type Manifold" https://stackoverflow.com/a/53037742

I only have F# experience so I can't comment about the ergonomics of the above. I love, love, love the JSON/Regex type providers. I'm trying to move away from SQL (to event sourcing) so haven't used that type provider yet.


> As an analogy, this whole discussion of PLs in CS circles is like complaining about whether we should use `dot` notation or `d/d(t)`

The fact that makes all the difference is that informal notations in math, science, linguistics and other fields are interpreted by human brains, human brains are flexible at filling the gaps and deriving most reasonable consequences from their incomplete descriptions. Symbolic notations outside of formal logic and programming are mostly an annotation DSL to augment humans communicating with each other.

In contrast, a programming language imposes itself upon you in a way that those notations don't. You have to describe a lot of things in it. Underspecification leaves too much to the machine, overspecification tortures the poor brains reading after you. The optimal boundary differs depending on the thing being described, might not always exist and sometimes not always that satisfactory (still pisses off the humans or the machines in some parts or another of the program).

Making different programs in different languages and making them somehow all cooperate to describe the same problem opens a whole new can of worms that's just as hard to solve as the original problem. It's nowhere near as hard to mix-and-match mathematical notations (e.g. Lagrangian formulation of classical mechanics where Newtonian dot notation is used to denote time derivatives and Leibnizian fraction notation is used to denote coordinate derivatives). If you're stuck, you can always invent a new notation or whip up a diagram, describe how they work on-the-fly in some shared meta-language, then use it right away anywhere and everywhere you want, including in conjunction with old notations.

So it basically boils down to the capabilities of the underlying machine. The human brain is one hell of a machine, you have a lot of leeway. But programming languages are primarily ways to communicate with a very different type of machine, and as if that wasn't enough they _also_ still have to support wet brains, and as if that wasn't enough they are extremely rigid and heavyweight compared to human notations, i.e. much more difficult and time-consuming to design and implement and spread (when they are new) and de-spread (when they are obsolete and there are better alternatives).


There are real differences between languages[0], but they tend to be less apparent than the syntactical fluff -- you have to get past the syntax to appreciate the emergent behavior of the language when you are solving a non-trivial problem in it. Also, what set of language features people want is often shaped by historical accident of what they're accustomed to, but also by the problem domain is. It's doubtful that there could be an "ultimate language" that's right for everyone and everything. One of Julia's creators quipped that designing a language isn't just a technical problem, it's also an exercise in applied psychology.

Thanks for point to Red, I'll have to check it out.

Yeah, I agree that it's about time we had more formal methods in software. OTOH, messing around with Dafny has been fun (well, I enjoyed abstract algebra in undergrad), but it takes forever to write anything useful.

[0]https://homepage.cs.uiowa.edu/~jgmorrs/eecs762f19/papers/fel...


It's easier to argue about programming languages than it is to argue about things that actually matter[0]. You start to realize that programming languages matter very little the more experience you get programming. Some languages are better suited for one task over another, but there is no objective "best" language.

This isn't to say that the choice of language doesn't matter -- it does. If your team knows C then you probably shouldn't try to start a new project in Java without some ramp-up/learning time. If you're working in JavaScript then you better set aside a lot of time before writing production code in Haskell. These are issues that are more related to people than they are to programming.

The best language is the one that you/your team knows. The second best is the one that suits the task.

[0] https://en.wikipedia.org/wiki/Law_of_triviality


(2) Red is just a (worse) REBOL variant, actually.


I think its more correct to call Red (currently) an incomplete Rebol variant but with loftier ambitions due to its Red/System & toolchain.


Can you elaborate on this please? (About it being worse)


This is one that blew my mind back in the day, compare these two quicksort implementations: https://rosettacode.org/wiki/Sorting_algorithms/Quicksort#C https://rosettacode.org/wiki/Sorting_algorithms/Quicksort#Ha...


The C code implement quicksort, the Haskell code does not. It has different (worse) space characteristics. Proper quicksort in Haskell is not a two-liner.


Is it a parlour trick in lisp or erlang?


It's a parlor trick, but a cool one is my point.


But you can make that parlor trick work ok in C too if you even the playing field by implementing a partition() helper separately.

The Haskell version reveals more of a deficiency in the C standard library than the language.


A sort is a sort or it isn't a sort? Don't get it. Is the claim that the first quick sort impl. in haskell on rosetta is NOT a quick sort?


Quicksort is a specific algorithm involving two array pointers and swapping values. The haskell implementation in question is not it. It’s not a “claim”, it is what it is.


A parlor trick that doesn't implement what it claims to, even if cool, doesn't make a point very well...


1) Try an array language like J or APL. Or some other paradigm outside the mainstream.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: