50
votes
Is there a programming language that brings you joy?
Just for a moment, forget all of the technical pros and cons, the static typing, just-in-time compilation, operator overloading, object orientation to the max...
Is there a programming language that you've just found to be... fun?
Is there one that you'd pick above all else for personal or company projects, if you had your druthers, because you would simply be so excited to use it?
And then, is there something missing in that "fun" language that's preventing it from actually becoming a reality (i.e. small community, lack of libraries, maintenance ended in the 80s, etc.)?
For me it would be Python. It's just so effortless, both the language itself and the amount of libraries and tooling makes it very easy to use for me.
The lacking thing is if course performance, I wish it was possible to use it for my daily work, but it's not meant to be.
Every time I need to pass around a function pointer in any C based language it’s at least 5 minutes of paging ‘how the hell do I do that again?’ back into my brain. In Python I’ve already defined a local function in a dubious scope and brought forth a new footgun into the world :)
But really, the fluency with which I can parse a bunch of CSV data (or whatever) into pandas and turn it into a somewhat publication ready graph has astounded multiple people at my office. The numpy / pandas / matplotlib ecosystem is lovely
Add a GUI library like tkinter or pyqt to the mix and you have all the raw materials for a small Intranet based ERP system ready in your toolkit!
I also love how straightforward Python is, especially coming from the C family. As far as prototyping goes, I haven't found anything more capable. However, I get very uncomfortable working with pip and all of the env stuff, and I sometimes wish I could have Python with typing.
Have you used F# at all? It's very different from Python, but the use of whitespace and the way it infers types (mostly) without needing them specified has always struck me as being somewhere in the neighborhood of what a smarter Python would feel like.
Seconded. I already made my argument for F# in this thread, but I really think that if you've EVER thought "gosh if only python had strong typing" you should try it.
Making the leap to functional is a lot easier in F# because you can still do things the normal way, and as the idiomatic stuff clicks it only gets better.
Have you used any of the type annotation stuff? It's pretty good for static checking with a few unusual corner cases exceptions where it gets weird. I mostly use it because it vastly improves the auyocomolete offered by vs code.
What I really want is runtime type checking. I think we will get it eventually, but there is so much legacy code, it will be a long time before it is required, if ever.
You should try PyCharm it works far better with annotated code, including better refactoring.
As for runtime checking, I don't think it is actually needed. I initially had a similar opinion about it being necessary, but if you think about it. If you perform check with
mypy --strict
and you don't get any type errors why would you get them at runtime? That would mean mypy doesn't check the types correctly. Also Python is already performing type checking at runtime, this is the major reason what makes it slower, adding additional checks for the annotations will allow it down further for no real gain.A better benefit is something that originally Guido said they won't do, but they did it anyway. Is ability to complete the code to speed it up.
The mypy comes with mypyc which allows to compile Python code and speed it up. This tool compiles mypy and makes it 5 times faster. You can compile your own code with it as well.
https://mypyc.readthedocs.io/en/latest/introduction.html
Python with Pyright is almost tolerable. Well, unless you use Django. I look forward to trying FastAPI one day.
Poetry also helps on the pip front a little bit.
Actually, python is a strongly typed language, it just doesn't impose on you the burden of declaring the types for variables you create. In that sense, strong vs weak and static vs dynamic are different type concepts.
This acts as both pro and con depending on how you look at it. Dynamic typing (though strong) will seem like blasphemy for those coming from Java/C#. The structure and discipline of static typing coupled with a compiler that detects errors in any and every path of execution right at the compile time will give you a certain kind of confidence or faith on your program.
Python, on the other hand, has this "let's just blast this off, we can apologize later if exception occurs" approach which is notorious for creating lazy programmers with impostor syndrome!
Oof, I think you've landed on exactly the reason why I always bounce off of Python, no matter how many times I try to learn it. I feel like I'm flying by the seat of my pants and have no idea what's going on when I use it, and (while I intellectually understand that this is not true) it feels like a language that I would never be able to improve in.
With C-like languages, it feels like all the logic is spelled out for me, and I just need more practice reading it and using it. It's much easier to assess exactly where my skill level is (or at least it feels that way), and that takes a huge weight off my shoulders.
You can have all of that. For project management I highly recommend poetry. It takes care of pip and virtualenv so you never have to worry about them.
As for typing. Since Python 3.6 type annotations were introduced. You can use mypy for your checking, but with proper IDE like PyCharm you can also get highlights of errors that typing caught (would still use mypy as it is more through), but more importantly you get correct autocompletion and refactoring will work correctly. This is why I add type annotations in every code I personally produce.
Yeah I use Python as my main language bc machine learning, but I'm trying to teach myself Go at the moment. By and large Go is still reasonably intuitive, but man does it make me miss list comprehensions. I love those fuckers.
Yes, I love working with it and use it for tooling and personal projects. It's just... so... SLOW... for anything intensive. I recently rewrote a Python program I was using at work in C++ because the Python program was the long pole in the performance tent. It went from 100% CPU and its peer process (C++ program that was doing a lot more work) at 10% to the other way around - the C++ version was 10% and the peer was 100%. So 100x change in CPU usage for doing the exact same thing.
I'm also reminded of one of my Masters classes on encryption. We had an assignment where we were each given a slice of an encryption key to brute force - one person in the class was given the correct slice (mind you, each one was a fraction of a fraction of a percent of the entire key space, we weren't trying to do the whole thing even collectively). Based on the reporting of the people who did it in Python, it usually took 40-50 hours of runtime to crunch through their own section. I did it in optimized C++ and just to show off, I did the entire 40 person class' keyspace in two hours.
As long as I fully control the computer I'm running Python in and I've no intention in moving the program to another computer or sharing it with anyone else. I reach for Python every time.
Why is that? Security issues?
Not really, it's that the package management/virtual environment side of things is a mess. It's very striking compared to younger languages like Golang or Rust, where package management is a dream by comparison. It's by far the worst part of working with Python imo, even worse than its performance.
I just read up on Python package management, and yeah, it sounds like there are a lot of pitfalls for the unwary.
And now that you read up on it and try to do it again in 2 years, EVERYTHING has changed again and there is a new paradigm and new favourite virtualenv tool for the community :D
Yes and I blame PyPA for all this fucking mess. Every time they're is some consensus they have to introduce a new way. They had setuptools (not great, but it worked and was bearable with declarative setup.cfg), they then had to force PipEnv, because it was a pet project of one of PyPA members. It turned out to be a complete failure.
Then they started depreciating setuptools without having a good alternative. It pushed many people (including me) to alternatives like poetry. As poetry was gaining traction, they decided to mess things up again by introducing their own tool called hatch. When asked what hatch adds to the table their argument was that poetry author did not agree with their new proposals (I guess it threatened their purpose).
So yes, I directly blame them for Python's fucked up packaging, and am huge proponent of poetry.
Try poetry is much better experience. Together with Nix you can lock down all the other non Python dependencies making a fully reproducible dev environment.
For my own use I created this: https://github.com/takeda/nix-cde it is opinionated, but it takes care of the boiler plate Nix code that is typically needed.
yeah I've heard poetry is better but it's not used widely enough for e.g. my coworkers to know about and use it. Not really looked into nix much, I'll check out your repo and do some googling around about it!
I'm a web developer, so I'd have to pick TypeScript. It started with the world's most janky language and polished it up to a level beyond any other dynamic language. Microsoft basically took JavaScript and threw PhD computer scientists at it until most of the flaws were gone. It's a dynamic language where the type system really makes you go faster. I've tried Python type hints, Ruby type hints, and written plenty of statically typed code. TypeScript is in the lead by a mile. And with TypeScript on the front-end and back-end of a web app you can import back-end types right into the front-end!!
If TypeScript was a little more REPL-friendly I'd pick it over Python for all scripting needs.
Completely agree, and the
tsx
library (somewhat confusing name, supposed to benpx
but for typescript) has dramatically furthered this for me. It even has a REPL! I basically don't include compile steps in my Node.js projects anymore;tsx
is so fast that it's easier to just run the typescript files directly at runtime.I also love to use Deno when possible (native Typescript!), though I often find that I need to fall back to Node.js for more complex projects.
Agree, and I'd add that even the old wild west JavaScript days were still more enjoyable for me than trying to build UIs in C/C++. I have a solid core memory of the first time I made a console application with C++ in my CS101 course in college. It was such a fun thing to quickly make a code change and see immediate results. During my MFC coding days that feeling was lost in trying to figure out what cryptic MFC error I was getting and why. My first time writing JavaScript felt like what MFC should have been, and brought back that feeling of immediate gratification.
Whoa, now that is a blast from the past. That should stay there.
I'm very happy I didn't stay there with it. 😂
Has working with untyped javascript libraries improved at all? I liked typescript fine until I had to start dealing with that, then it became torture.
I haven't used it in a year or two.
Yeah you can pretty much always just install the
@types/<package>
package and you'll have a type interface for the untyped package. If it's an obscure package you can either use it un-typed or write your own type interface (which should just take a few minutes for a small or simple package).At the time I was working with a mapping library and a GIS library. Neither had types available and I had so much trouble figuring out how to use them, it was incredibly frustrating. Neither was small or simple. At the time there weren't any available typed libraries at all for the functionality I needed.
It's not enough to stop me from using it over javascript, I just wish there were an easier way to manage this.
Something I've had luck with is copy/pasting the docs for a library into GPT-4 and telling it to generate a TypeScript type interface for it.
Haha, that's a really good idea.
As of now it's Rust.
It ticks all my boxes (high level enough, static types, builds for the web) while being different enough than the languages I use for work (C# and TypeScript). It also helps that I exclusively use it as a hobby language, so I associate it with more fun code.
In a work-related context though, I'd choose TypeScript. It's the language I'm the most comfortable with, and it's pleasant to know exactly how I'm going to write something before even opening my editor. It's a different kind of joy I guess.
I've always referred to it as the "Dark Souls of programming" since you're always battling the compiler and it just feels so good once you survive. Great language to work in, but hate the traits and lifetimes system.
I’ve been tinkering with Rust for a while now. I respect the design decisions and being forced to clean up a lot of sloppy code. The one thing I’ve been struggling with has been working with Results the correct way. I feel dirty leaving a bunch of question marks and unwraps everywhere. I’m sure there’s an elegant and proper way to do it that I just haven’t learned yet.
EDIT: I'm also so new to it that, when I'm not actually battling the compiler errors and it appears that I've done something correct with borrowing/mutability/Result/Some, I feel like I got lucky in some weird sense. I think I just need to get more comfortable with the language and read up some more.
Yeah someone compared Rust as "the dark souls of..." and that's not wrong.
The thing with dark souls is that they beat your ass not just for the sake of it, but to force you to learn how to dodge, parry, and punish enemies. Then once you understand how the game works, it suddenly clicks and the game becomes enjoyable.
Rust will hit you with the borrow checker until you understand its rules, and then you work with it and no longer against it.
Question marks are fine.
.unwrap()
s on the other hand, are ugly by design, because you're telling the compiler "I know something might go wrong here, but trust me bro, it's fine, and if it isn't, it's ok to crash". And it could very well be fine, but if you have an.unwrap()
every other line, that's a sign you're getting a bit too confident, and there are too many potential crashes in your code.I personally just start with unwraps everywhere, and the second my code crashes I go to the relevant one and write some basic error handling there. This helps me move fast while still handling the most common errors.
Rust has a lot of helpers for that. I got a lot better at Rust when someone pointed me to let var = Ok(some_var)` etc. (I might get the syntax wrong so please correct me, Rust is a hobby language for me). Also, "?" can be a completely valid way to handle options/errors
Can you expand on what you mean by this? I'm not a fan of javascript, and I haven't had an opportunity to get into typescript. So if Rust could fill that spot, I'm very intrigued.
Not OP, but I made and released a web app in Rust.
You can compile Rust code into WebAssembly, which most modern browsers are able to execute.
I'd recommend Dioxus if you want to try it out, it borrows from React a bit so it might feel familiar to you if you ever used React.
Shiny! I will take a look. Thank you!
You can "easily" set wasm as a build target for Rust. I use quotes because wasm is rarely straightforward, but with rust there are enough guides and tools to make it as easy as possible.
"Builds for the web" is a requirement for me because it's the lowest common denominator when you want to distribute your work. Wasm libraries and games can be safely used by virtually anyone.
I think the coolest part is that Rust is one of the few languages I know (I'd love to hear other examples) of where you can just compile a native app to web and it "just works*"
Dunno about the "it just works*" part, but pretty much any language used in the modern world compiles to WebAssembly in one way or another: https://github.com/appcypher/awesome-wasm-langs
But yeah, Rust feels like the most mature language for WASM, mostly because they both started around the same time (2 year difference IIRC) and found a community of people interested in both.
Since you enjoy Rust so much, I'm going to ask a bit about your "builds for the web." I'm trying to learn how to build a web app that has most stuff in HTML pages with some dynamic function injection on the backend, so it can read from and write to a database. I would also like SASS support.
I've been trying to follow Rust on Nails, and it's potentially a bit outdated, enough that I've run into some issues with it. I'm currently on the gRCP section and it's at a point where stuff just... isn't working at all.
Do you have a suggestion for a similar tutorial, or even just recommended stack for this use? I'm not the best with Rust currently, but a long while ago I did build a very simple terminal-based game in it, so I know I can use it if I can just get back into it.
I don't have any solid recommendation, sorry. I tend to use Rust for other things than web dev, as that's already my day job :) "Builds for the web" for me mostly applies to ease of distribution, not webapps/webservices.
There are a few resources on https://www.arewewebyet.org/ though, good luck!
What do you mean by dynamic function injection?
Basically just PHP-esque portions in the page that run on the backend. It didn't click for me that it's even a possibility until I saw this HTML templating language for Go (Templ).
Looks like rocket has a templating engine. But it’s different. You’d compute serializable values and then stick them in a hash map, pulling them into pre-written templates.
Right now it's ruby. I've just started to learn it and so far it reminds me a lot of python, but I find the syntax to be more natural and easier to use.
If only there were more libraries. It seems like all the niche stuff is on python by default.
Yeah, for me Ruby is a genuine pleasure to use. Fortunately I’m a web developer, so there are libraries that do pretty much anything I could want.
I know a lot of people love Python, but the idea of syntactically meaningful whitespace horrifies me.
Ruby was purposefully made to make developers happy and I totally get it, despite initially being revolted by the language. I used to be a Python evangelist but every time I switch back to Python now I crave the expressiveness of Ruby blocks and its “everything is an expression” syntax. I know a lot of people are turned off by it but the way you can easily create custom DSLs is wonderful.
The libraries aren’t quite as good as Python (particularly for data science), but it’s never been a major hindrance for me.
For quick one-off scripts I usually choose Python or BASH, but anything beyond that Ruby (on Rails) just feels much better. Maintaining sanity in a large Python application has always been a challenge for me (even though I obviously know it can be done).
I just can't get over the fact that
3.times.do
is valid Ruby =) Every bone in my programmer body says BLECH at the syntax. Primitive numbers aren't supposed to have methods.Hilariously, my original comment called out that exact method but I removed it for brevity.
You learn to live with it because it’s a very rarely used method of iteration and the whole paradigm of attaching a ton of methods to the base Object becomes more natural. I think some languages implement that concept better with traits or similar paradigms, but it doesn’t bother me too much anymore.
I, on the other hand, absolutely love the fact that it's valid syntax. It's just so simple and so clear: do thing 3 times. I love reading good ruby code, and ruby makes it easy to write pretty code.
BTW it's
3.times do
Same. I have this weird almost sentimental connection to shell scripts, despite their awful maintainability (I recently learned Google outright forbids Bash scripts longer than 100 lines, and tells the people responsible to immediately rewrite in a different language) and lack of cross-platform-ability, unless you’re writing POSIX sh… but it’s just what I was first exposed to as a kid, on a then-already aging Macbook, and first got to witness what’s possible using a command line and one’s own, quickly programmed code instead of a mouse/GUI.
(And most of that behavior has, well, stuck :D)
I don't know if it's bias because I learned ruby before python, but I still sometimes think about the good ol' days when I did all my scripting in ruby. I guess I haven't really analyzed why, but it just feels nicer to me. Unfortunately, python is just more useful now, and I'm more used to it at this point, so that's what I use for everything these days.
Lisp is my mother tongue. I miss its beauty.
IMHO lisp-likes (I especially like clojure) may not be the easiest languages to fix a problem, but after they are done they tend to be very readable and easy to mantain and follow. I think there's a very special joy on that.
Python has like no friction, but I very often find my scripts to be very hacky since they are just made for specific things. A large app in python can be hard to mantain.
Rust is something I really like, as it has everything I feel lacking in C++ (my day to day language) but honestly I wish the borrow checker was smarter. Making some data layouts is a massive PITA.
C++ however is just horrible. The std is dysfunctional and every module has its own way of doing things, I discover gotchas often and new stuff is often undercooked. But the worst of all is building, one of the worst systems. This is especially true when crosscompiling.
I learned LOGO when I was maybe 7.
A few years ago I realized that the reason Scheme and recursion in general felt so much more natural to me was that LOGO is a LISP with no parentheses.
There's a python library for it. I've been considering going back over some of the Advent of Code puzzles that lend themselves to traversing a grid.
For most purposes, C# (and the dotnet ecosystem in general). It's the one I'm the most comfortable in, it's what I use for both my work and most of my side projects. It gets out of my way, but can dig deeper when I need to. It has a sane builds and dependencies system. I think people sell modern dotnet short because their views are tainted by assumptions from old versions that haven't been true for years and/or anti-microsoft bias.
From a different perspective, Zig. I love seeing what Andrew and the team are doing with Zig, and I hope it succeeds further. I think the simplicity of comptime and the power that it offers is a really good idea.
I did a lot of C# early in my career, mostly in the form .NET desktop apps and the occasional web app. But then my company moved to Mac and Linux, and it was no longer compatible. It's definitely a nice ecosystem.
Good news - modern .NET (aside from desktop UI apps) is very cross-platform. At my job, we've shifted from a large web app deployed on IIS on Windows to an Azure-native system that's mostly deployed in Linux containers in k8s.
It is now, but it wasn't that way back when we switched away from it. I don't think I could convince my company to abandon Go/Python/JS in favor of .NET at this point. But it's something I'd like to explore myself to see what's changed, considering I haven't touched C# in over a decade.
How do you feel about Zig? I used to struggle a lot with C++ syntax and eventually stopped using it, do you find Zig easier to use?
Caveat here that I haven't written a lot of Zig yet. I think Zig feels more like a C successor than a C++ successor, mostly given its much lighter object-oriented nature. That being said, if you're looking at syntax in particular, going from C++'s templates to Zig's comptime is a massive difference in the positive direction, in my opinion. Instead of having to learn an entire new (Turing-complete!) language to do metaprogramming, you just... Write Zig.
Don't think I'll be jumping into metaprogramming at the start, but that's good to hear, thank you.
I love C# and .NET:
It's my go-to for nearly everything.
The only areas where I can really fault it are:
If I want to go fast or prototype, then Python, for all the reasons others have mentioned. I know people do, but I would be hesitant to use python in production if the product was critical in any way. The snag I always hit is errors in the error handlers. Test coverage and static checkers can only get you so far, IMO.
I have also come to really enjoy Golang. I'm doing AoC in Go this year. I think Go is the "logical end" of what you would get if you took C and Java, took out all the bad stuff and added back a bunch of quality-of-life improvements, and took a "reasonable person" stance on style decisions.
I haven’t used it in a bit so I don’t remember the exact implementation I used to make the function take an unknown number of variables but you can do something like
func hollow(v interface{}) {
return
}
And call it whenever you have unused variables that you don’t want to deal with while debugging. Makes them technically be used without having effects on your code or needing useless print statements.
The zero-effort cross-compilation is what keeps me coming back to Go.
In the time it'd take me to figure out what's the virtual environment du jour in Python and get it running on a random computer I might not have root for I can just feed the Python code to GPT-4, have it translate it to Go, compile it to whatever architecture the destination machine is running, move it there and have it running =)
I've done this multiple times. Prototype with Python, GPT to Go and it just works.
Wow. I really have to get into coding with AI.
The free GPT3.5 version tends to hallucinate the code pretty badly, but GPT-4 is definitely worth it.
Ha, I feel the same way about Go that you do about Python, though for a different reason.
I've joined projects before which had large Go codebases. It seemed impossible to find pieces of the implementation until you'd basically memorized the structure of the program. I've never had this issue with any other language, Go is just decoupled by design.
This isn't a one time thing with specific people creating the codebase, it's multiple teams at multiple companies which had people working on this code who were very good at their jobs.
Oh, I agree, I hate that implicit dependency mapping stuff.
I am not a fan of programming (none of it brings me joy!), but I have been doing and thinking in it since I was six years old, so the more apt-term might be "addicted" or even "brainwashed" into always doing it.
The one that I always enjoy most writing in is C, especially when I don't have to bother with memory for short scripts. I love scripting in bash, and I am really starting to fall in love with Lisp, but thats early days. Odin is so nice to tinker in and makes me happier to read and use, but has some weird issues on deploying.
I've started messing with Mojo, and that might be my ideal joyful language that could make me fall in love all over again, but that language itself is so early.
F#:
Functional Language, but not strict.
Python minimalist syntax. No pointless {}'s and ;'s everywhere.
Strong typing with type inference.
If it compiles it runs 90%+ of the time
Immutable by default.
Options instead of nulls.
Piping.
Can still use any OOP style if needed (for loops, side effects, whatever).
Access to all dotnet stuff (bit of a mixed thing but mostly good).
and probably a lot more I can't think of or appreciate.
The only real issues I have are -
The dotnet thing means that sometimes the library you want to use is using more traditional OOP style syntax, and since it's a smaller language, there's often not a F# specific one. You can make a wrapper, and there's really good language specific options for some things, but it can be annoying when the general response keeps being "well just use blah...". ESPECIALLY with front end where you can quickly wind up writing more js than F# (although looks like giraffe view engine and HTMX is the solution I need for that).
It really really sucks to go back to any other language. I hate the endless boilerplate of C#, python's typing is just asking for problems down the road and I hate some of their syntax legacy, I really don't want to do memory management, and most other functional languages are too strict and can get in the way of faster development.
F# with libraries like Fsharpplus to wrap C# functions is really nice. It just works really nicely. I love when you made a bunch of functions and put them together and it just clicks.
Figuring stuff out in Perl is so incredibly satisfying. If only I could understand the code a month later.
I like using Perl, but I think the culture around it is unhealthy. The whole cult of Larry Wall thing managed to sidetrack development into something so incompatible with the existing language that they don’t even call it Perl. And back around 2000, when Perl was pretty much the ideal solution for web development, the existing user base was so unfriendly to people trying to learn it that newcomers were essentially driven away, to the point where hardly anyone uses it anymore.
I don't know if I'm at the level of 'joy' yet, but I've found myself writing more and more Golang for microservices. There are definitely things about it that annoy me (like marshaling json to/from structs with extra tags because json keys are typically lowercase, and Golang uses variable case to determine public/private scope). But overall, I find that the application does what I want it to do on first compile/run with fewer bugs/failure than something like Python where I have to do a lot of retry/rewrite as I go.
I've also been enjoying learning Vue, which I now prefer over React.
Wait, that isn’t a joke?
As someone who has never written Golang code, that sounds like Python’s “whitespaces are relevant”, nightmared up a thousand times. I assume it’s not as bad in practice, but that alone kind of makes me want to… not touch Go code? I don’t know, this is probably an initial overreaction, lol.
Also, if you don’t mind, could you elaborate on what you like in Vue or what makes it different over React? I’ve been meaning to get started with a proper web framework for a while now. I assume the choice doesn’t really matter. For context, in terms of web, I’ve only really written some amateur-level PHP code until now.
It's not a joke, and it's not just a convention like @trim suggests. It's legitimately how Go declares public and private variables without using keywords. I'm really not a fan of that, but it's not bad enough for me to avoid the language entirely. Overall, I like it and it's nice for microservice development.
In terms of Vue vs React, I prefer Vue's HTML templating instead of JSX, and I like some little things like the way Vue handles emits (instead of React's callback model) and is overall more opinionated since it's a framework and not just a library (I actually like that). That being said, React is way more popular so the community is much larger and deeper. Also better from a job market perspective.
That's a bit different, global and local variables aren't necessarily related to public and private variables.
Public variables are variables you can access outside the package from other Go code, and private variables are limited to just the package they're defined in. A private variable can be a global variable within the package, though, like in the guide you linked.
At least according to this guide it really is not just a convention but will result in a compiler error if you try to access a private (= uncapitalized name) variable or function outside the package
https://www.digitalocean.com/community/tutorials/understanding-package-visibility-in-go
I found the interactive tutorial on go.dev to be one of the best introductions to a programming language I've ever seen. It was a great way to pick up the basics.
In addition to what @HoolaBoola said, Go encourages you to organize your code into multiple packages. It's pretty much the only way that the language supports namespacing and is simply defined by what directory the .go files are in. It's natively how you organize logic to encourage reusability. So it's quite common to need access to variables from another package within your same module (the parent to packages) or project. And that's where the annoying variable case issue comes in, especially when dealing with json or yaml.
I would agree. It definitely felt alien at first, but after a while it was fine. Syntactically, it reminds me of Python's convention of prefixing private vars with underscores: in both languages, the name of the variable encodes its accessibility. Python doesn't enforce it, but it strikes me as a similar concept — and I think I like Go's take on it slightly better.
(I have my own gripes with Golang, such as the various sharp edges concerning arrays and maps. But public/private variables isn't one of them.)
There's a lot of reasons to not touch go. Imagine if the language developer thinks you are too dumb to grasp any advanced programming concepts. That's pretty much the experience. The only nice thing about the language is the approach for parallelization with using channels go routines, but that is pretty much it.
As someone who is programming in multiple languages (C, C++, Python, Rust, TCL, Java, PHP, Lisp, Nix), Go is far from bringing joy. I think it is that attitude of its developers that I'm just too dumb to grasp any advanced programming concepts and I'm just left with simple operations and copying the code.
As for Python. I currently enjoy it the most. After typing annotations were added, I started using them everywhere. With a proper IDE like PyCharm, they allow me to catch many bugs, the auto complete works correctly and refactoring code is no longer scary (it just works). I highly recommend it. Also add poetry for project dependencies handling and the experience is awesome.
I really enjoy working with Go and I find it strange that it gets so much hate. It's a very pragmatic language with great tooling and performance.
Yeah, agreed. But language preferences are one of those things that developers love to disagree on in general. Doesn't matter what language it is, someone loves to hate it.
I posted this in a different thread the other day, but I really like playing with Elixir. I first tried it out in the Advent of Code a few years ago and could easily get the correct answers on the first try. No worries about off-by-one errors, side effects, etc. I particularly like the multi-definition functions and the pipe operator. The functional style and overall syntax seem to make it easier to decompose programs into chainable blocks that just work.
It’s elixir for me—while the syntax can look a bit odd at first, you eventually realize it’s composed of a small number of basic elements with several layers of optional syntactic sugar on top. At its core, syntactically, it’s similar to a lisp. The language’s creator has actually described it as a lisp-2 language once or twice. This allows for robust and relatively user-friendly macros.
Separately from the syntax, the BEAM runtime’s focus on actor model/shared-nothing concurrency means you can (and are encouraged to) create applications that behave like a network of fault-tolerant mini-services rather than a single monolithic program. The way you structure your logic is just very different from other languages, and in a good way. You also don’t need to reach for additional technologies as often—for example, it’s trivial to set up a cache without memcached or the like, or cronjob-like tasks.
Having used elixir as the backend language at my job for the past 3 years, I can truthfully say that tracking down and fixing bugs in our elixir code has never taken more than a couple hours. The immutable functional style within each elixir process, and the supervisor tree / actor model between processes, generally makes for a very resilient and observable system.
For personal projects, Rust by a mile. It feels like the most modern language out there (probably because it's one of the most recent) and people are so obsessed with it that it runs on any platform ever (even in a browser!). They also took all the good parts of object-oriented programming and made them even nicer.
For work projects, Python. Everyone knows it, and if they don't, it takes like a day to get the hang of it. It's also probably the most documented. Runs on Windows, runs on Linux, it has a library for anything, and it's easy to write very readable code with it. However it's just as easy to write absolutely incomprehensible shit with it too - something I'm currently dealing with.
I also hated Java for most of my life, but I tried it recently and it's not so bad anymore? Not going to use it for anything, but I guess I wouldn't mind working with it if I had to.
For me it never was, but I really curious, could you explain what irks you so much about Java previously?
I think I found it incredibly verbose and tedious, and to be fair I think the book I read when I was a kid was about Java 5 or 6, so the language has evolved massively in the 12 years since then.
I was also a picky kid, with a superiority complex - because I knew C99, other, higher-level languages were "inferior", especially languages like Java and Python which don't get directly compiled to machine code.
I promise I got better (I'm using Python extensively now, as per the original reply). Also I now find C powerful, but ineffective for modern tasks. If I ever do low-level development I'll definitely pick C (or try no-std Rust maybe?) but otherwise I would never pick it for anything that can be done successfully using a memory-safe language.
Forth is a language that I have little practical use for but still find fun and interesting to tinker with. It really is amazing what you can get out of the very simple concepts it's based on.
6502 assembly is another, though I do find some practical use for that in the sense that I actually apply it to end goals, not just aimless tinkering.
I get a sense of satisfaction about using Zig for my current main project. But if anything, it's fun for the kind of reason I should forget for the moment!
I had the other "Brodie book", Thinking Forth!
Oh, that's cool. I've been meaning to try that, but I don't want to have any justification for paying for the real thing, so I'm reluctant. My favorite 6502 project so far was a small game for the Atari 2600. Brilliant and at the same time absolutely horrific hardware design.
Just looking at Zig for the first time right now...
Wait a second. So I can just start using this on top of my old and outdated C codebase and just start incrementally using features from Zig?
Yeah, you could rewrite it module by module and import and use your C code directly in Zig!
That said, the language is very much a work in progress at this point, but I don't regret it for a second.
I'm curious about Zig too. How do you feel about its syntax? I used to struggle a lot with C++ and eventually gave up. I guess the syntax is still evolving, does it throw you off when there's a change?
I have a background in C programming, and the learning experience hasn't been too bad for me. After the first thousand lines of manually translated C code I think I had a firm grasp of the basics. There were some syntax shortcomings early on that I feel have been addressed now. For example, for what in C99 would be
the equivalent in Zig would be
I.e. two statements, contained in a block not to leak
i
into the outer scope. Now, since a while back, the for loop works over ranges as well as collections, so you can perform the equivalent like so:Changes like that are usually additive and not very disruptive (except to satisfy the compulsion to rewrite the few such loops I have in my code base), but there are other changes to the language and build system that have been more disruptive. For example, when I downloaded the latest master build the other day, the compiler had started considering variables that aren't being mutated as errors. That said, I don't think I've spent more than half an hour between each update I installed fixing things that broke, and in this case I of course ended up with more easily digestible code.
I don't have a ton of experience with C++. From memory, I can probably create and instantiate a class, evaluate a template or use a namespace, but I've always seen it as "C with Extra Stuff™" where a lot of the Extra Stuff is things I have to look up as I go, some of which is great and some of which seems like anti-patterns encoded in the language. Zig seemed more compelling to me because while there certainly is a great language that allows for high development velocity existing as a subset of C++ which is a great tool for those that have found it, I think the language as a whole has accumulated a ton of cruft that makes it unnecessarily hard to learn and navigate. The same goes with C, to a lesser extent.
That was me too, and I never got comfortable with a lot of the Extra Stuff.
Appreciate your thoughts. It's sounding like adapting to changes isn't difficult (and could be fun). I'm definitely going to check out Zig.
Syntax changes from version bumps have been considerably less of a headscratcher than I expected. And I do largely love the syntax with only a few gripes.
Some stuff I had adapted from translated C broke going 0.10.1 to 0.11. The compiler told me right away where to look. I'll give you a brief on the most complicated to follow along. @intToPtr had changed to @ptrFromInt, which was easy to see in the release notes. The release notes also explained what work I needed to do after
zig fmt
'ing which was polite. I was wrapping some windows C types inside those ptr casts, so those builtins changed too. Curiously trying to auto translate the source C for comparison no longer compiled, but it did give me an idea of how to do it and I fixed everything in about five minutes, when just looking at it I expected to sleep on it angrily.The docs that exist, and reading the zig source itself are both great, but I'm overall dissatisfied with the only other reliable source being discord, and the gradual fragmentation of documentation through peoples' projects on github on disparate versions of zig.
However, Zig remains exceedingly pleasant for me to use and the official package manager was much less disagreeable than I anticipated. The build system seems to change very frequently, which I dislike, but it remains Zig and I haven't done any project big enough to give me problems, I can use the autogenerated build.zig just fine or look at one of the updated big projects.
I think that covers my version bump experience, weird place to end it but oh well.
Thanks a lot for sharing your thoughts. So far Zig (and what the developers are doing) is sounding great. Hopefully docs will consolidate as Zig matures and finalizes.
BASIC 7 on my old Commodore 128.
Not even joking, really. I came of age at a very auspicious time for personal computing- machines were finally affordable enough that a family could buy one, complex enough that you could do genuinely interesting things, and simple enough you could hold the whole machine in your mind. That last part in particular is, I think, underappreciated, even amongst fellow techies.
I work in the IT mines to pay the bills, but holy hell do I hate everything about trying to build reliable systems with bricks made of damp sand. So much so that I'm transitioning away from the field. It's a pain treadmill filled with middleman subscription leeches and perverse incentives across the entire stack that don't align with personal computing.
So for joy, it's back to hacking on old machines, or smaller hardware projects with, say, an attiny and simple C. Because it is understandable across the entirety of what it is, and once you have that, then creativity and joy can happen.
Ocaml brings me joy for completely inexplicable reasons. I'm not particularly good at it, but I found its syntax very intuitive from the start. It definitely helps that I'll never have any reason to use it for work, so its a retreat from work stress and I think a bit of nostalgia from before I had to code.
A specific language? No. But there are specific contexts that I enjoy. Specifically anything where I can write a relatively short script that has immediate visual results. I guess the most common thing is hacky webpage interactivity scripting.
By far my favorite language is R, because it gets out of my way as a language and lets me focus on doing stuff with data that I'm interested in.
Although probably the fluency that comes after many years of use create a bias, there are design desicions that make it enjoyable. The tidyverse and tidymodels in particular bring me joy, because the end result - to my biased eyes - typically looks readable en elegant.
I have fond memories of R. In my econometrics class, we always had to use something called Stata, which seemed like a more expensive and dumbed down way to work with data. I would do all of my homework in R since it was just better in every way, and then translate (forge) the output to what Stata would have shown.
I stopped using it a long time ago but it always seemed like a great option for very specific use cases.
Caveat, I have never worked or trained as a developer, and I do not have any intention to become one. I am just an amateur who dabbles in programming as a hobby.
I typically find C-like syntax to be the most enjoyable to use, and my favorite of those (just for the pleasure of writing code, not for actually getting things done) is, unsurprisingly, C. I would enjoy it more if it had a native string class, though.
However, I think the language that I have found most fun to write in is Lua, even though it is extremely different from C (and every other language I've tried).
I think the common thread here is that they are both easy-to-learn, but not easy-to-use. I don't like learning languages and combing through their myriad features, but I love making things myself from scratch, so they are perfect for me. I find working in a very simple, feature-poor language as fun and engrossing as playing a puzzle game (but more motivating because I also get a program at the end that I can use).
You might like to give Wren a shot, it's somewhat similar to Lua. The syntax takes a lot of cues from C, and it can compile to c99
I don't know of any compiler for Wren, other than how it compiles to bytecode before running the interpreter. Is that something new?
Yeah you're right, I misunderstood the line "It compiles cleanly as C99, C++98 or anything later." on the Wren homepage, which is talking about the Wren VM.
Ooo!
I looked a little at Lua a few weeks ago but haven't played around with it much. Tables (and metatables) seem versatile and cool, but has there been anything you want to do that it (or the rest of Lua) doesn't do easily? Doesn't have to be anything sophisticated, I'm a hobby coder too and all my projects have been small.
I would not recommend Lua for most large, serious projects, except maybe as an easy-for-non-programmers-to-learn scripting language (e.g., for a game that offers mod support). It definitely has limitations.
However, for smaller hobby projects, I strongly recommend giving it a go. It is well-suited to making simple games, art tools, etc.
It's quick to learn, so you even if you don't end up liking it, you won't have sunk a ton of time into it. Just be aware that is very unlike other programming languages, so many of the concepts will be totally new—and other concepts may conflict with what you have already learned (most gratingly, Lua starts counting from 1 instead of 0).
Thank you, I might spend more time with Lua and LoVE.
PHP. It's just so fucking easy to do anything. I like getting things done. So. It's nice.
The evolution from the old days of mysql_ and php 5 up to the current version have been huge for the language. It also doesn’t hurt that there are some really great frameworks in Symfony and Laravel.
I don’t necessarily love working in PHP per se, but I do have a lot of fun using Symfony.
I love working with Perl.
I don't program much now, but I took a programming class a while ago structured around a Java textbook that I really enjoyed and remember having had a significant effect on the way I structured my understanding of things in general (I'd say because the language feels philosophically tractable). Python though has always felt weird and unsatisfying, and I could never get into it.
I haven't written Java in 10 years, but I remeber writing Java after having read Effective Java and feeling like I could conquer anything.
I recently started writing Java again, and some of the changes between 8 and 17 have really helped bring down the boilerplate. It's moving in the right direction.
I totally get that appeal. When I realized that my IDE could trace back how any given piece of code worked, even when it was a basic thing included with the JDK, it really got me excited to program. It's very different from the "Just trust me and do things this way" that a lot of other environments tend to have.
Since no one else has said it yet, my nomination is QuickJS.
It’s a JS engine that can be called from a shell much like Python, Perl, etc. The author is Fabrice Bellard, who’s well-known as a founding author of ffmpeg, qemu, and quite a bit more - so the implementation is rock-solid and highly-efficient. There’s a minimal stdlib and C API to make the runtime extensible and useful for scripting.
To be honest, I haven’t found too much practical use for it, since it lacks the “batteries-included” toolkit of Python. Unless used as an embedded language in the tradition of Lua, I see it more as a competitor to awk or jq. In my limited experimentation, however, the map/filter/reduce paradigm is a great fit for simple command-line scripts, and hits a real sweet spot in terms of composability, expressivity, and readability.
Most recent ones that have captured my interest:
Awk (it’s got a lot of cred but I feel like people sleep on it in 2023)
Elixir/erlang/other BEAM languages (I love how integral concurrency is to the whole system. most other concurrency implementations in other programming languages i have used really felt hacky, “bolted-on”, and implemented in a manner that required me to do a lot of mental gymnastics to actually fit the abstractions and ideas underpinning the rest of the language)
Forth
Id agree and just say it ... Bash. 😃
When I was still writing code for performance, it was the pairing of Groovy and Java. I'd prototype in Groovy (including rigging a test harness), get whatever I was trying to do working, then port to Java and pop open a profiler to get the speed to where it needed to be.
These days, I'm mostly teaching and building code that's meant to illustrate one concept at a time in Python.
For me, there is nothing quite like Kotlin. It is pure pleasure for me. It just makes sense to me in a way most languages can't. Every other language makes me wish I was working in Kotlin. Rust comes close, but comes with the kinds of considerations while coding I could do without.
The vast array of available targets, reusable code between server, client, & various UIs, the simple dependency management for each of them in gradle, extension functions, the lambda function argument syntax, the null safety (and functions on nullable types!), the explicit mutability with immutable as default, very well structured concurrency, the flexibility in writing scripts, batch jobs or services...
There are 3 main blockers to its adoption I think:
Personally, the one thing I wish it had more of was control over vectorized/parallel instructions like SIMD or GPU computations. These currently have to be handed off to more native solutions (which is entirely possible for many targets, with native compilation or JNI for instance). I'm hopeful but I do understand it's a bit niche as far as use cases go.
Java frustrates me because I feel like I have to write the same thing over and over. Lombak helps with this, but I don't feel it should be necessary to depend on an external library like this.
Kotlin was like a breath of fresh air. It actually manages to make Spring usable and I was able to teach both AT THE SAME TIME to folks without any trouble.
I think back on my time using Standard ML (SML) pretty fondly:
I really like how clear functions can be using clausal function definitions.
You can pattern match on arguments to express some decently sophisticated logic in a concise way.
Auto-Currying
A function that looks like it accepts many arguments
is syntactic sugar for a function that accepts one argument, and returns another function that accepts the next one:
Type Inferencing
SML is staticly typed, but you seldom have to annotate types yourself. Even on function definitions! The type system, Hindley-Milner, does a pretty good job at figuring it out.
Though I'll admit that:
A more mainstream answer would probably be Kotlin, which I ended up picking up to contribute to an Android app I use.
Single Expression Functions are cool syntax for writing really simple functions
Scope Functions are something I miss when I switch to other languages
As an added bonus,
fun
is literally the most important keyword in the language!My preferred language would be Zig, it's just improved C with perfect metaprogramming.
As far as syntax goes, I enjoy writing Nix expressions. So I should probably try Haskell or something.
You might want to take a look at Roc. It's a very young language, but the goal is to produce something similar to Haskell or Elm that compiles to native binaries or WebAssembly.
I code mainly as a hobby, all my projects so far have been small. I like Haxe, but not sure I'd use the word "fun" to describe any language.
Thinking about algorithms, planning out how to structure code in a way that's reasonably efficient and cleanly represented by the language's syntax and capabilities (so the specific language does matter here), running the incomplete but gradually growing code, I find all this fun (when I don't overthink). Installing (including everything you want to use like the IDE, libraries), debugging, trying to figure out obtuse error messages, waiting through long compile times, all that is usually not fun.
So languages could be fun in the sense of minimizing the unfun stuff. I think Haxe does well here (though I don't have experience with many languages to compare it with), it supports a fast compile to bytecode and I don't struggle with it's syntax.
I also like Haxe for the "cool factor". Multiple compile targets (including bytecode), cool features that I actually use (like abstracts) and some that I don't (like macros that operate on expressions rather than strings like in C) but I still find very cool conceptually. That's also fun in a way, just using a tool that you find cool.
Haxe has a relatively small community. Haxe's official documentation is succinct and to the point, and not a lot of tutorials made for the language and its libraries, I did struggle learning some things.
I like Python too for short bits of code, but for anything split up over multiple classes I prefer something statically-typed.
While in college, I really loved C and got to write some Assembly along with it during my first job. I loved the low level fancy solutions some of my coworkers wrote. I’ve since moved to web dev, which is kind of fun in its own way, but I still miss the low level stuff. It always made me think there was so much more to figure out. I’d love to go back to pointers, bit masks and piecing together app state from a core dump. So my pick would be C or Assembly, just to feel lost again.
I actually love Dart as a language. It was originally created to be familiar to Java programmers, so it's kinda "boring" in that regard, but over time the team has basically reinvented the language to add new features, some of which have come from community requests. In that way, it's like the anti-Go because it has broken compatibility like a hundred times.
What I love about it is that it's still a fairly boring language, but it fixes so many issues that many other "boring" languages have. Null safety, lots of convenient operators, a fairly rich standard library, expression-based control flow, (some) pattern matching and destructuring, and it's all statically typed.
I started programming again in the last few months and have really been enjoying working in dart. There's no one thing in particular that stands out as game-changing about the language, but I'm having a great time anyway.
It's "success by a thousand cuts".
C++! There's so much wrong with it and the whole board that makes some wild decisions like grafting other languages' features to it. But at the end of the day there's just a beautiful verbosity to it, youve got every tool in the box to accidentally dismember your foot and i love it.
Clojure, hands down.
It:
I’ve long held the opinion that Clojure criminally underused in business settings; it basically checks all the boxes for a dependable, consistent, performant language.
Julia, people say Python is easy but I find Julia much more consistent and easy to use (looking at you conda/pip).
Python when I want to make things work and Rust when I want to write art.