The examples on the home page are a nice way to quickly show the features of a language. I'll check the documentation to see how to work with files, make HTTP calls, parse JSON.
It's the first time in more than 10 years that I actually feel like trying a new language. The last time was Elixir. Since then I had to use Lua (hobby project) and Python (work) but I don't enjoy them much. I would have skipped them if I hadn't have to use them. Before Elixir I enjoyed Ruby, before that it's been Perl 5 in the 90s. Everything else I used in that period and before was because I had to (C, Java, PHP, JavaScript/Node) and I skipped many other mainstream languages because they didn't look nice to work with (Go, Rust, TypeScript.) I still have to see what's writing and running a Rhombus programs looks like so I might discover that it's not so nice after all. I'm hopeful.
TypeScript & Rust don't "look nice to work with" because they force you to write maintainable code that doesn't just stop working because of a random runtime error. In my opinion, Go looks nice to work with but actually is a hidden monster full of footguns.
Curious to read that because I’ve always had the opposite opinion of the above:
Typescript looks nice to work with but the tool chain is horrible (this isn’t really Typescripts fault though, more a synonym of it having to compile to JS).
Go looks horrible to work with (too simplified syntax) but is actually really nice because the tooling is (mostly) spot on and it’s simplified syntax weirdly helps with maintainability for large projects that have evolved over multiple years.
I guess this just goes to show how much personal preference can be a driving force behind our platforms of choice.
> Typescript looks nice to work with but the tool chain is horrible (this isn’t really Typescripts fault though, more a synonym of it having to compile to JS).
It's not even inherent to TS that the toolchain must be a morass of moving parts and multiple config files, as shown by Deno in contrast to Node.
The constant incantation of if err != nil is bad for my aging hands and frankly hurts even more when you see Rust's single-character error marshalling using ? operator.
I have aliases for these kinds of general things (in vim) for most languages i use. Eg. if im inside a typescript file i have a mapping produces if ($obj) { $ } and i tab to enter the next "$" to insert the correct things.
The same goes fo Go. I have a mapping for if err != nil { ... } and the cursor is places inside the block.
I dont understand why people dont use this kind of thing for the most common programming constructs.
I would suppose they do and are free to do it - however, liberally having to spread it all over the code hurts readability. I'm sure people can say in response to that after a while you stop noticing or that their favorite IDE can collapse it and so on. It can be excuses all the way down instead of admitting that it is a shortcoming of the language.
You say it hurts readability but most of the time I want the unhappy paths to be visible.
Coding software that works when conditions are met is easy. Coding software that works when things break is hard. So I want error handling to stand out because it forces errors to be handled visibly and properly.
All too often I see Python programs drop to a stack trace under normal execution or JavaScript return cryptic errors that don’t mean much to anyone bar the core maintainer. But I seldom see 3rd party Go software bomb out in quite the same way. And I think that’s in large part because Go doesn’t try to hide errors away as an inconvenience that we shouldn’t be looking at.
So I’ll agree Gos approach is ugly. But sometimes good software does just look ugly. And the way I see it, it’s the quality of the compiled software that matters more than the beauty of the combination of characters that built it.
I am not questioning it's effectiveness. I have written Go code that is chugging along without issues in Production. My point is ergonomics and effectiveness are not mutually exclusive - hence the example of Rust's ? operator - effective and ergonomic (Rust also has issues with difficult to read lifetime+trait annotations).
The sad part is that people have been talking about this for years but Go team stubbornly refuses to make error handling more ergonomic.
Most of the stuff on there is just talking about general programming mistakes. Eg overly nested code is a problem a developer can make in any language.
Sure there are some Go specific stuff in there. But the whole thing reads more like someone preaching an irrational hatred for something rather than a fair breakdown of genuine footguns.
The issue is you need to explicitly recover each goroutine just so a nil dereference or a panic from a library you have no control over doesn’t bring down the whole application. Maybe this is the way it has to be, but it is a little known fact that might bite you.
The only time a library should be panicking is if they’ve reached a state they cannot continue from.
I’d be interested to know which libraries you’re working with where this has been a problem because I’ve only ever experienced one occasion where a 3rd party library panicked unnecessarily.
Simplified syntax helps with maintainability for large projects? You're talking about a "modern" language which had no generics for the better part of its life? The language filled to the brim with "if err != nil"? Go is horrible to work with.
Exactly, Typescript doesn't stop working because of random runtime errors, it stops working because you didn't update the toolchain tangle last Thursday and then some configuration file got out of whack with the tsc defaults ;-)
Technically TypeScript doesn’t force you to anything other than writing valid JS code. Its design was great for wide adoption but also suffers from the JS part.
While Typescript has the gaping hole that is typing external data. Your code can't enforce that in TS, but in Go you're forced to.
I do admit Go has an easily found foot gun: nil pointers. It's a small one though, in comparison to the original problems with nil pointers. More stubbing your toe than shooting your foot.
From Rhombus you can call all the Racket libraries. I used Racket in a few projects:
* To edit a Moodle backup file, I used Racket to unzip it, find the xml file, parse and filter some of the parts of the xml file and then zip the new version.
* To autoreply some emails, I used IMAP, then scrap some info from my webpage and then SMTP.
There is also a JSON library, but I never used it.
The only problem is that some libraries have no wrappers still, so instead of the expected snake_case name you must use the spear-case with some delimiter to make the parser happy. (Something like |spear-case| or {spear-case}, I should check the docs.) And if that annoys you too much, it's easy to write a macro with a rename transformer so you can use the nice snake_case name, it adds a negligible compilation time and no penalty at run time.
I found Kotlin a "typed Ruby" (I found Ruby a "sane Perl").
Rust seems pretty nice to work with (good DX) in it's domain: close to the metal programs were every tick counts. The main DX issue with it would be compile times.
Go's awful to me from a DX perspective as it is lacks proper error handling. Compile times are great though.
Maybe OCaml is a good fit for me (and you!). Fast compile times and good error handling.
TypeScript suffers too much from being a JS superset. JS has horrendous DX imho.
Interesting. I learned Ruby a long time ago because a Perl expert told me Ruby was getting good. I like Typescript because it's really easy to read and maintain without breaking anything. But you can't do this: `next x.map { _1 + 3 }.sum if sth`. I guess I should give Kotlin a try then.
After 20 years of Ruby I didn't know (or didn't remember) that next can have an argument. I looked it up. Thanks.
BTW, I never liked the _N arguments. Too cryptic. They make me stop and think on details instead of just read the code and concentrate on the important stuff.
x.map {¦n¦ n + 3}.sum
is immediately clear but I guess that it's very subjective.
Such details are so subjective even a same person could change his/her mind about it and change it back later...
I think they did a safe job of adding this _N feature though, since it's not allowed all the time. It felt like a missing feature because you could do map(&:to_i) but needed a parameter for something simple like map { |x| x == 5 }.
The `next` keyword is interesting in Ruby. It can be used as an explicit return for blocks.
In javascript, for comparison, there is a `continue` for standard loops, but non-standard blocks don't exist so they are functions and require the use of the return keyword (except for single-instruction arrow functions). And implicit returns or nexts simply don't exist in js.
Even the same customer has projects with Ruby ranging from 2.7 to 3.4 so I'm using the oldest possible syntax. The changes in keyword args hit hard some projects. Luckily not the one I'm working on most of my time.
It's the first time in more than 10 years that I actually feel like trying a new language. The last time was Elixir. Since then I had to use Lua (hobby project) and Python (work) but I don't enjoy them much. I would have skipped them if I hadn't have to use them. Before Elixir I enjoyed Ruby, before that it's been Perl 5 in the 90s. Everything else I used in that period and before was because I had to (C, Java, PHP, JavaScript/Node) and I skipped many other mainstream languages because they didn't look nice to work with (Go, Rust, TypeScript.) I still have to see what's writing and running a Rhombus programs looks like so I might discover that it's not so nice after all. I'm hopeful.