Free zones are great but last I checked (around Jun) you will need to travel to Dubai every 6 months to keep your PR/Emirates ID active, if you don't intend to live there.
Happened to me. I was that unfortunate CTO for a fintech startup. Unqualified CEO with anger issues but with loads of money waited till past traction and nod from investors, then simply booted me and my team out on some lame pretext, going as far as bad-mouthing 2 years of hard work by the tech team and now the CEO and the board have ghosted and won't return calls/email to pay or honour employment contract terms! Sane advice above, DO NOT accept equity, always go for hard cash, lesson learnt the hard way!
Would be nice if a little more detail were added in order to give anyone looking to do the same more heads-up to watch out for potential trouble spots. I take it the workers are polling to fetch the next job which requires a row lock which in turn requires a transaction yeah? How tight is this loop? What's the sleep time per thread/goroutine? At what point does Postgres go, sorry not doing that? Or is there an alternative to polling and if so, what? :)
I just spent months working on a large piece of software and could say without a doubt, Lisp is awesome! But I also want to say that most implementations are hashing out a spec written decades ago and not trying to improve what's obviously lacking -- a full modern standard library! Trying to piece together functionality from here and there (and Quicklisp which is an unversioned mess) will only take you so far and in the end you will realize the amount of time wasted chasing this great language! AFAIK Lisp needs more backing from the heavyweights to make any reasonable progress which I'm sure won't happen.
I quite agree, so I'm making a meta-library to have useful libraries available out of the box: https://github.com/ciel-lang/CIEL/ It's CL, batteries included. You can use it as a library, as a core CL image (loads up faster), and as a binary to have a REPL, and to run scripts:
ciel --script myscript.lisp
(edit) or just
./myscript
with a #!/usr/bin/env ciel shebang.
where you have access to HTTP clients, JSON parsers, CSV readers, DB drivers… and much more, out of the box.
I’ve noticed many lisps and schemes are not set up to simply accept a single file name as the sole command line argument, which is something common to nearly every other platform. Seems like an easy target for reducing friction for newcomers.
I think every programmer that tries common lisp eventually comes to the same conclusion, however none of the new versions of "standard" libraries got any traction to my knowledge. Usually it's used only by the author who created it which makes their code unique in some sense, like a recent post from Ron Garret [0].
The spec is really valued by cl community and I guess I'll tell an unpopular opinion now, but I think there could be a place for an ecosystem built around one of the compilers like sbcl with all the old cruft removed and a really good all purpose standard library (similar in capabilities to the one of go for example). What that will achieve is that it will allow new developers to write the code without reading on why the things were designed is a certain way 40 years ago because of now forgotten os or hardware limitation.
What part of Common Lisp would you consider old cruft and what value would removing it bring to the language that would offset the value we have from having one of the most stable language definitions still in use? I can think of a few dusty parts of the language that are rarely used today but it's perfectly safe to ignore.
Lisp has a good all purpose library ecosystem, it's just informal rather than baked into the language, and I haven't had any significant issues with quicklisp since it came out however many years ago. Writing portable common lisp is not at all difficult and there is no problem like with say Scheme of one library needing a specific compiler. And libraries tend to have a long shelf-life too. How much of Python's standard library is old cruft with better alternative packages available now for example? Didn't they have to prune a bunch of stuff in the python2->3 transition? There is considerable risk in including standard libraries in a standard, and the risk is that those libraries will end up being outdated eventually. You want to add more potential for more old cruft to be in Lisp and then pruned again? Why? Just use quicklisp or one of it's alternatives that are cropping up.
Lisp is not Go, it's an agreement between many different parties about what lisp is, it's not a codebase under the defacto control of one organization, or even an informal group or "community". This is extremely valuable and recent events around Go show why, I am extremely glad that I never payed much attention to Go because honestly I cannot trust it's governance model, but a specification that hasn't been and won't be updated in decades I can trust completely, and if one implementation betrays that trust, I can always move to one of the many alternatives listed in the OP.
sidenote:
> I think every programmer that tries common lisp eventually comes to the same conclusion
if this refers to "Lisp needs more backing from the heavyweights", then OH GODS PLEASE NOOO! I want to write code that will run in a year without modification and won't have some corporation put spyware in my compiler while trying to convince me it's for my own good and have my IDE slurp my code to train some LLM to make it easier to pile even more pointless unmaintainable code upon the world. The "heavyweights" have shown themselves very poor stewards of the discipline of computing indeed.
Someone proposed adding telemetry to the compiler. People reacted to this as they usually do to telemetry. Google reacted to this as they usually do to criticism.
>Google reacted to this as they usually do to criticism.
Which is how? Not been folllowing them lately, for obvious reasons, so interested to know how they react these days.
Constructive non-egoistic non-spin engagement with the critics / stony silence with compressed lips / furious rebuttal / muttered denial and then look verbally down at the plebs while giving each other group-affirming backslaps in their posh pubs? With guilty looks in the mirror after the party and then downing some Valium to salve their conscience and get some sleep?
A few years ago, after Common Lisp being my favorite language since around 1982, I thought that I might switch for my personal projects to Racket Scheme since it does have good library support. What holds me back is that I have found plentiful work opportunities over the last several decades with Common Lisp, but except for getting paid by Springer-Verlag to write a Scheme book, I have never been paid to use Scheme.
Also, to be really honest, so much of my work in the last ten years has involved deep learning, that I have somewhat reluctantly learned to love Python for writing short programs.
But no one is stopping you from building a "full modern standard library". I am doing just that with https://github.com/galdor/tungsten. Of course it would be nice to have a large company do all the work as it is the case for Go, but it is not going to happen. As always, you either do the work yourself or pay someone to do it.
The specification is limited, no doubt about that, but I am convinced that any modernization effort would end up in a huge mess with everyone trying to inject their own preferences from the languages they already know with no regard for the spirit of the original specification.
It's about the packages, a Quicklisp dist has a list of packages of specific versions (like libfoo 1.1, libbar 1.0, and libbaz 1.2) and you can switch to an older dist (which can have libfoo 1.0, no libbar, and libbaz 1.2).
+1. came here to say this! it's in prod, making money; bring up the discussion of full rewrite with the management at your own peril. learn to tame the beast by pruning one dead/redundant function at a time, that's the best you can do, both for the project and for yourself!
I'm a Ruby guy and I tried Crystal for about 2 years and absolutely loved it but then had to give up for the following reasons:
1. Too slow to compile (the whole program + the entire stdlib is built everytime you build!). No incremental compilation available.
2. No language server (apparently it's just impossible due to the way the language works). Tbh, I'd be happy with just "Go to definition" but alas, no-can-do!
3. Obscure error messages (macros are to blame here)
4. Weak HTTP server implementation -- making things such as a fetching POST params or uploads incredibly frustrating. Once read the request body cannot be read again.
5. Weak/non-existent Windows support
6. No multicore support
7. Obviously small community
8. Nil handling takes a bit getting used to (coming from Ruby)
9. Error messages are hard to read with overloaded methods wherein just the types are used without any indication of what doesn't match
Overall, if the above changes, I'd switch to it in a heartbeat!
> 3. Obscure error messages (macros are to blame here)
I feel like this is a bit strongly influenced by the macro experience.
Macros are an advanced and powerful feature and naturally more complex to debug.
In general, Crystal's error messages are often praised for their clarity and helpfulness (especially compared to dynamically typed languages, of course).
> 4. Weak HTTP server implementation -- making things such as a fetching POST params or uploads incredibly frustrating. Once read the request body cannot be read again.
The stdlib implementation of `HTTP::Server` is intentionally very bare-bones (many programming languages don't even have such a practically usable feature in stdlib).
Specialized web server implementations are available as shards (https://shardbox.org/categories/Web_Frameworks). They're based on the foundation in stdlib and provide more advanced features.
> 5. Weak/non-existent Windows support
Windows support is pretty stable and almost complete by now.
> 6. No multicore support
Crystal has supported multi-threading as opt-in via the `-Dpreview_mt` flag. It's considered a preview, because it's to be used with care when dealing with data structures that are not thread-safe. But it has proven to work well in production use.
> 8. Nil handling takes a bit getting used to (coming from Ruby)
But once you're used to it, it's sooo much helpful. It just helps to avoid a lot of potential bugs which you would have to take extra care for in Ruby.
> WSL is still the best way to run crystal in windows.
WSL is never the best way to do anything, unless the question is "what is the best way to emulate Linux on Windows?". In all other cases, WSL is literally the worst way to do anything.
This specifically installs the Visual C++ Compiler and the Windows headers so that you can get a command prompt with all that in your PATH. It is not a full-fat VS install. The difference is something like 20-30GBs for the full VS install vs 1-2GB for these specific components.
Have you ever installed Visual Studio? I have. Even just the build tools DOWNLOADS 1-2 GB, as other user mentioned, which is still 10 times what you get with other options.
I also tried it now and then. There are too many places to have concurrency and scaling issues with such a tiny community. The packages and feature sets are thin too.
Alternatives: if you don't mind your eyes bleeding with C++-verbosity and tracking liveness yourself, there's Rust. Sure Go looks cute until you have a million users emailing you trivial questions they should've asked a group.
And if you want something similar to Crystal but with even stricter and more granular semantics than Rust with an even smaller community. there's Pony. It was built around the Orca GC. There's Nim too. Finally, one can use Haskell to built that critical payment service and maintain absolute job security. Meanwhile, the Erlang/Elixir OTP stack stays performant, although no one is quite sure how to package, deploy, and manage its lifecycle properly.
> 2. No language server (apparently it's just impossible due to the way the language works). Tbh, I'd be happy with just "Go to definition" but alas, no-can-do!
The technical challenge is that a Crystal program needs to be inspected as a whole. Simplified, changes in location A can have effects on some completely unrelated location B. That makes it hard to cache intermediary results and a semantic analysis needs to cover the entire program (including the standard library), not just the files that were changed since the last time.
This applies to the responsiveness and memory consumption of the language server as well as the regular compilation process. So this is an important topic, and we're working on improvements. It's a complex topic, but there are some ideas.
Good to know. I've got zero emacs skills and I'm on vscode and nothing works there. From what I understand the lack of type info until the whole program is compiled creates this issue.
> 2. No language server (apparently it's just impossible due to the way the language works). Tbh, I'd be happy with just "Go to definition" but alas, no-can-do!