The ones I can get things done with:
- Python
- Zsh
My current obsession:
- Factor
Honorable mentions:
- Nim
- Roc
Well some of these seem less known (which I am interested in). I only know python and zsh. I’ve heard of bum. Can you tell us more, and why you like them?
All of these languages are relatively succinct, and I rely on that to reduce visual and mental clutter, because I have a pea brain.
Factor, Nim, Roc, and Zsh each offer, to differing extents, some argument-then-function ordering in the syntax, which strikes me as elegant and fun, and maybe even wise. In that order, Factor does this the most (using postfix/reverse-polish-notation and managing a data stack), and Zsh the least (piping output from one command as the input for the next command).
Roc
Roc is a functional language, and an offshoot of Elm in spirit. The lead developer and community are great. Relative to Elm, it’s more inclusive and experimental in the development process, and does not primarily or exclusively target web stuff. They aim to create an ambitiously integrated development environment, especially taking advantage of any guarantees the functional design can offer.
Here’s a sample, using the
|>
operator a lot, which lets you order the first argument to a function before the function IIRC:getData = \filepath -> filepath |> Path.fromStr |> File.readUtf8 |> Task.attempt \result -> result |> Result.withDefault "" |> Task.succeed
Nim
Nim is so darn flexible and concise, has great compilation targets, and employs Uniform Function Call Syntax to more implicitly enable the kind of ordering in the Roc example. And you can often leave out parentheses entirely.
Factor
Factor is a full-on postfix and concatenative language, tons of fun, and turns my brain inside out a bit. I made a community for concatenative languages here on programming.dev, and while there’s little activity so far, I’ve filled the sidebar with a bunch of great resources, including links to active chats.
EDIT: [email protected]
The Factor REPL (“listener”) provides excellent and speedy documentation and definitions, and a step-through debugger.
One idea that seems absurd at first is that for the most part, you don’t name data variables (though you can, and you do name function parameters). It’s all about whatever’s on the top of the stack.
In some languages it’s awkward to approximate multiple return values, but in a stack-oriented language it’s natural.
In Factor, everything is space-separated, so functions (“words”) can and do include or consist of symbols.
[1..b]
is not semantically something between brackets, it’s just a function that happens to be named[1..b]
. It pops 1 item off the top of the stack (an integer), and pushes a range from 1 to that integer on to the top of the stack.Here it is in my solution to the code.golf flavor of Fizz Buzz:
USING: io kernel math.functions math.parser ranges sequences ; 100 [1..b] [ dup [ 3 divisor? ] [ 5 divisor? ] bi 2dup or [ [ drop ] 2dip [ "Fizz" "" ? ] [ "Buzz" "" ? ] bi* append ] [ 2drop number>string ] if print ] each
And in image form for glorious syntax highlighting:
Factor example walkthrough
Anything between spaced brackets is a “quotation” (lambda/anonymous function).
So:
- Push a range from 1-100 onto the stack.
- Push a big quotation that doesn’t end till
each
at the bottom. each
consumes the range and the quotation. For each element of the range, it pushes the element then calls the quotation.dup
pushes a copy of the stack’s top item. Say we’re in the ninth iteration of theeach
loop, we’ve got9 9
on the stack.- Two quotations are pushed (
9 9 [...] [...]
), thenbi
applies them each in turn to the single stack item directly beneath, leaving us with9 t f
(true, it’s divisble by three, false, it’s not by 5). 2dup
copies the top two, so:9 t f t f
or
combines the last two booleans:9 t f t
- Two quotes are pushed, followed by an
if
(9 t f t [...] [...] if
), which pops that finalt
and calls only the first quotation. [ drop ] 2dip
takes us from9 t f
tot f
– it dips under the top two, drops the temporary new top, then restores the original top two.?
is like a ternary. That first quotation will push"Fizz"
if called witht
(true) on the stack,""
otherwise.bi*
applies the last two items (quotations) to the two values before them, each only taking one value. The Fizz one applies tot
and the Buzz tof
, taking us fromt f [...] [...]
to"Fizz" ""
append
joins those strings, as it would any sequence:"Fizz"
- Finally we
print
the string, leaving us with an empty stack, ready for the next iteration.
EDIT: Walkthrough in image form, more granular:
Hi there! Looks like you linked to a Lemmy community using a URL instead of its name, which doesn’t work well for people on different instances. Try fixing it like this: [email protected]
Ah I love Factor! So many cool aspects of that language.
C# was my favorite language to use, though I haven’t touched it in 7+ years because I don’t do any windows or desktop UI development anymore. It feels the most expressive and doesn’t get in your way too much. It has all the mainstream OO language features while not feeling overly burdensome like Java.
Go is now my favorite to use because it’s super fast at runtime and I don’t have to deal with a bunch of environmental and framework nonsense at runtime. It’s hands down the fastest runtime for serverless lambdas, which is the majority of my work. I have several gripes about the language, namely the embarrassment that is their implementation of type inheritance and generics, but the lack of ease for the developer is offset by performance. Java handles that stuff better, but I’m not trading a little ease in dev cycles for 20x longer cold starts and 5x poorer runtime performance. (Actual stats based on some use-case specific testing we did)
TypeScript is my fav for frontend dev (React), but it’s not as if there’s any choice there. I used to be a plain-JS psychopath, but then I had to work with other people on projects and TS makes that waaaaay easier.
I was listening to a podcast on SE Radio a few years ago when they were interviewing some high performance stock trader (or maybe even the NYSE engineers themselves, I don’t recall) and they were talking about how they used
sun.misc.Unsafe
to basically do the low level memory operations that lower level languages allow. I don’t remember their reasoning on why they were using Java instead of an actual low level language but it was still fascinating.I think newer versions of the JDK have been making it difficult or impossible to access that class though.
Curious about the tests you made with java and go. Did you test classic JVM or the new native builds?
We are currently using mainly java with some node sprinkled in there, but I try to move some thinks we have from K8 pods into lambdas as it doesn’t make sense having it running 24/7. One of my coworkers often looked for a reason /place to introduce go. So might be helpful info for him haha.
I don’t recall which Java environment was used; I’m not a Java developer so some of those technical details went in one ear and right out the other. They did implement snapstart for Java lambdas and that made the warm start time similar to Go. But the runtime performance isn’t even close after they put a bunch of effort into trying to optimize it.
I truly can’t recommend anything other than Go for lambdas. It’s better by every metric and it’s a lot easier to manage your infrastructure (just a single binary file with no file or environmental dependencies; it doesn’t get any more straightforward than that.) I’d definitely recommend doing a PoC to compare performance for your specific workload in Java vs. Go. As long as you have devs capable of writing Go, it’s a real winner. If you don’t, I’d still go with nodejs lambdas over Java; Java still seems to require a lot of tweaking to get its performance comparable. It’s a 30 year old swiss army knife, and it shows.
Thanks for your answer.
It’s a 30 year old swiss army knife, and it shows.
There is a lot of improvementsn happening in the Java space , so that might change over the next years.
It’s better by every metric and it’s a lot easier to manage your infrastructure (just a single binary file with no file or environmental dependencies; it doesn’t get any more straightforward than that.)
With these new native builds you also get a single binary file as far as I know ( I’m still kinda new to Java) and much better startup times. So today Java might perform a little better in this comparison.
But I take it as a good chance for getting a chance to introduce go as a language.
.net core now has all the framework stuff and all runs great on Linux. C# is a really nice language.
Yeah, my team maintains a C#/.NET SDK and we don’t use any windows machines. We use mono for compilation, because that was the only option at the time the project started, but hope to make some updates soon to be able to use the newer targets that have native cross-platform support. Microsoft has come such a long way with .NET!
Clojure. It’s just fun to write.
Firstly, it’s functional and “Lispy”. My code is super expressive. Writing code is like writing prose where I can choose a word (function) from a large vocabulary [1]. I can focus on high-level concepts and modifying states instead of fighting with low-level logic.
Secondly, it runs on JVM - an already robust and performant platform.
And there are so many good things that I cannot simply write in some words. The father of Clojure, Rich Hickey, is a genius in expressing Clojure’s design. You should check out some of his talks [2].
Too bad that Clojure is too “niche” that I haven’t got a chance to make a living by writing Clojure, yet. But learning it is one of the best decisions I’ve ever made in my career. Yes, it’s that good.
I enjoy C#. Learned it through game development in Unity.
Currently learning GDScript, because reasons… It’s easy and simple, but I still prefer C# though, I’m not a fan of dynamic languages.
StandardML, but without the module system, I would rather want a typeclass/trait/interface.
Typescript followed by Ruby
Typescript as the web has won. Ruby as nothing else feels closer to poetry
Scala 😀
Had to scroll far to find this. Love Scala!
C Bash and Go. I feel like I can do pretty much anything with this trio.
But Java is my paycheck language.
Go
I’m tired of not having a proper parallel/async model in my languages
Go gives me confidence which key for imposter syndrome.
I like v because it uses the c backend instead of llvm or wasm. it’s really fast
F# is awesome! One would think it’d be more popular
I just discovered nim and it seems nifty
Short answer: C.
Long answer: depends on the task.
Longer answer: bash for scripting in general, kotlin for android, C++ 'cos i have to maintain it but it’s far from favorite, PHP if i were to do web backends. My to-learn list includes COBOL, Ada and maybe Rust (waiting for all the hype and evangelists to die down a bit). Something functional like Erland or Scala would be interesting just to fuck around with the brain a bit.
Any particular goals with Ada? Had an academic curiosity for a few years but never used it in earnest.
That’s pretty much it: academic curiosity.
HTML
deleted by creator
PHP! Super easy in use, allows for very fast deployment, is secure, and there are boat loads of libraries available
It used to be C++ but I got tired of being a language lawyer over time. Rust is my current favorite since it does the language lawyering for me, but it’s not a strong favorite. I’m waiting for Zig to hit 1.0 (which will be a while) since it hits a sweet spot for me.