My opinion on languages
This is a Work-In-Progress blog post. Perhaps if I make them public I will actually finish them
Language discussions are completely useless, use what is best for the job.
However that doesn’t mean that some languages have ridiculous pitfalls or missing features that makes our (developers/users/operations) lives better
First, let me state that I appreciate all the hard work of the entire language development world has given us over the past 60 or so years. Each language over time was introduced to fix problems, or improve the then “current way of thinking”.
It can be difficult to understand at times how or why certain languages prevailed while others died. Other times is is obvious why they became obsolete/absorbed.
Please do not take any of my opinions as attacks to the hard work everyone has put into their projects. It is much easier to critique then to build and maintain.
These opinions also come from a very much junior Developer with bad opinions. I only started programming seriously in the past couple of years.
With the preamble done and the excuses said, let’s get this ball rolling!
No language actually sucks, or better said:
Every language sucks in some way, perfection wouldn’t need to be redone every year
Saying which languages you could with a simple yes/no is actually quite simple:
Can this language solve this problem, in a reasonably efficient way?
The kicker for that question is the “reasonably efficient”, as this introduces a huge grey-zone in the yes/no question which dependent on who you ask will shift towards one side or the other.
Combined with not specific questions this can be an excellent, well actually moment.
Is a bicycle a good mode of transportation?
Yes. It allows you to transport yourself easily with little effort to vast distances as compares to walking in a reasonable time.
Or:
No. Moving multiple people and some tools on a bicycle would be the worst thing I could imagine.
Both answers are of course valid, they just interpreted the use-cases differently of the transportation device.
Let’s get a bit more on-topic.
“Should I use JavaScript or Typescript for this project”?
“Is Go better than Rust? I heard it is better”
“Why don’t we just use python?”
“Zig is better than C”
All these questions can go either way depending on certain criteria. Today however I won’t go into when you should use what, not because there is an extremely simple answer to it (just do it in rust), but because it is not possible to decide based on a blog post what you should use. Think about your use case, knowledge you or your team have, make decisions based on reasoning and two blogs or three.
What I am to present you today however is what i think each language does well and bad.
??? add something about, not for business to choose, but something else…….
Like anything we can categorize in buckets, as long as you have an infinite amount of buckets. We will choose only some of the infinite:
- Learning, time investment to understand language and ecosystem
- Developing, does the language want to be build
- Discovery: can i discover what i can do with this? (more ide than anything) but functional programming languages have a big min point here. And untyped languges with bad code (no type hints)
- Debugging, ????
- Testing,
- Using the Software, performant? ???????????
- Hosting, is it cheap to host?
- Sharing, college, users, grandparent
??? levels, know if i can use it(scoping). know what i can do with it(types). know how to use it(Memory wise, locks etc)
??? what do i need from a language, and why would i dislike or like others
??? I don’t learn languages to find a job, some jobs do require specialization in a language but learning anything and properly helps you create software in any language
My opinions are also skewed in my desirable programs. I find for example not needing to specify my types everywhere quite convenient when writing a simple script. But most often than not, when working on something larger it would be nice to know what something is
Learning
Learning a language is interesting, if you come from nothing you take everything at face value. When coming from another language you (i at least) start to compare at every intersection “that’s weird why not like I am used to?” or “pff how annoying”, and if you like the new language more “woaw my previous language should have done it like this”.
The communities of Python and JavaScript always proudly present that their language is simple to learn. And a quick web-search would tell you that these are seen as the easiest languages to learn.
And this also makes somewhat sense, scripting languages were always meant to be simple to use and run. But both Python and JavaScript are incredibly confusing if you haven’t use a language before to “program”. Programming here means something you might do in your head or verbally.
If I have more than 5 chickens, I should get a bigger pen.
Or in pseudo code:
if chickens > 5 then
bigger pen
endif
But structwafel, you can do this in python:
if chickens > 5:
bigger_pen()
And that is correct! Excellent observation reader.
My problem with most languages is not what you can’t do, but what you can do.
Humans have a great brain, which can think and make you act on a lot of things. Sometimes it might be better to not do things, but this brain of yours is not perfect.
Having languages limit on what you can do can, accelerates the learning of a language. Only of course if you are not biased on your current view. Exceptions to rules are annoying to learn.
“
If branches will only execute if the condition is true. And a condition is true when it is True, or when people decided something is True
“
Python, but more so JavaScript, have problems (I see them as problems) like this can make learning a language confusing.
However, this is also depending of course how you view what true
means. And I had difficulties understanding Thruthy
values for programming.
And so does every language have their own quirks.
- pythons types
list, dict, set
are passed by reference. But change to value when you rebind - Java’s integer caching, string pooling, needing to learn JVM besides java
- Go nil maps which behave differently if reading (zero value) or writing (panic) behaviour
- Go nil interfaces, annoying for non error interfaces
- javascript, the entire language is a quirk
- Rust’s nightmare which is cancellation
These are just the first quirks that came to mind, feel free to tell me all about the quirks you find in your languages. And these quirks do not carry the same weight ofcourse. The worst I encountered of the above is the cancellation problem in Rust.
Learning the language is not only about the quirks, they are just little gotchas which halt your progress for a while. The size of a language, ecosystems, discoverability and conventions are a much bigger part.
The more complicate a language is, the longer it takes to learn. But it is also hard to quantify the size of a language. I think the size of a language should be proportional to the discoverability of the language.
If there are a hundred ways to print something to the screen, I should be able to easily find all hundred ways without needing to research or scour through documentation. For more complicated things it obviously makes sense to, but at times some languages/paradigms let me down on this regard.
Most functional languages are beautiful by design, you have values, you pipe them around, great success. However needing to understand/extend can be frustrating due to implicit typing of f#, or bad discoverability due to not knowing what is possible with what you are holding. (LSP/ide tools should be able to fix this)
For now if I had to set a number 1 winner in this category, it would obviously go to Go-lang. It is an small language, there are no complicated ambiguities. You can’t do fancy things which are not obvious on first sight. At times it might feel a tad verbose, however that doesn’t have an impact on learning the language. If the “most complicated go code” in a code base is a function which returns a function which returns a function, I think you have it quite oke.
func myMiddleWare(v1 bool) echo.MiddlewareFunc{
return func(next echo.HandleFunc) echo.HandleFunc{
return func(c echo.Context) error {
return handleXYZ(c, v1, next)
}
}
}
Developing
Let’s assume we have learned our language, how is it to write with it? Is there support in all your favorite editors? Are there tools to assist you?
??? basically all modern used languages have all the support you need,
Not knowing what you can do with a language, or needing to keep alot of contexual load when writing can feel frustrating. This is my main paint point of untyped languages, every time i look at my 200 lines of Javascript i need to follow every source to re-understand what things exactly are and do. Python codebases which do not type-hint/strongly document, or use mypy etc, are also codebases where discoverability means you need to read everything to know what is going on.
For me these mishaps make developing in those environments feel sluggish. The language is not helping you in understanding the semantic meaning of the code. This of course has more to do with how the software is created than the language, but the language in which something is created is one if not the biggest influencer in the smell/taste of the software.
Rust is a language which in my eyes really wants to be built, with rustc errors and clippy’s helpful messages it keeps you on track on writing great software.
error: incorrect use of `await`
--> client/src/lib.rs:82:13
|
82 | await tx.send(Message::Text(message))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: `await` is a postfix operation
|
82 - await tx.send(Message::Text(message))
82 + tx.send(Message::Text(message)).await
|
The module system is great at seperating concerns, publicity of struct
,traits
etc can be scoped as needed. But in rust you need to stay aware what is allowed with the borrow checker and what is not.
“ Can this struct have a dyn
object? Will I need in 3-5 hours do something which makes it not possible to have one? “
You need to be very proficient in Rust to not paint yourself into a corner at some point. This can also be a source of interrest.
As said previously, Go is very simple. But there are some painpoints with how package scoping works in go. To use a library, you need to know all name-spaces which that library uses. The library fun-stuff
might have their types under fun-types
and some other things behind fun-other
. The current lsp/ide tools don’t make is easy for me inside a function to use unknown name-space of libraries. In rust, I at least, it is possible to fun-stuff::xyz
and figure out what other packages (modules in Rust’s case) this library has. Together with Go not allowing unused variables to build, or not allowing to re-assign. Makes it slow for “check this line or that line and run test”.
???
end of thing
****** verbosity is a good thing
Assuming you know what data-types exist, general control flow, here are some of the things I try to figure out in a language:
- Syntax, you need to learn how to write.
- Built-in functions / standard library
- Error handeling,
** python quickrs, Truthy, mutable default arguments, indentation errors, dynamic typing
categories: Learning, Developing, Testing, Debugging, Hosting, Using, Sharing(dev, user, grandparent)
Why do i always write in rust? It makes me want to program