I've also been liking Go quite a bit recently. I know it's a language HN loves to hate. It's not as expressive as some other languages. But I feel like creativity within constraints can also be rewarding (kind of like writing a haiku). If I can find a way to reformulate my problem so that it can be expressed easily in Go, I'm often happy with the result. And because the abstractions Go provides are not very costly, it usually executes efficiently too.
It's hard to find a language that combines high level features with the lower level features that performance-sensitive apps often need (like value types, control of memory layout, etc). Also GC simplifies a lot of things, and Go makes it practical for a wider class of applications with sub-ms pauses and making it easy to minimize allocations. C++/Rust involve more programmer effort around ownership, and C# can also involve more programmer effort since minimizing allocations is trickier and GC impact is greater. It's not a big language but the combination of features / trade offs seems really practical.
Go's also widely used enough where you don't need to worry about having a robust library if you need HTTP2 or something.
I like the simplicity of the syntax. Arrays and objects are easy, closures are easy, and I like prototypal inheritance as a concept, although you're not supposed to actually use it in practice.
Lua is probably a close second, though. If I were to design a programming language, it would probably be somewhere between the two, with some C++ features tossed in for flavor (operator and function overloading, maybe generics.)
The JavaScript community has taken a horrible turn towards complexity. I’ve been planning a fork of the npm tree, to return to ES5. But it’s a big project and I want to be ready with a good modern, modular web toolkit before I do.
(The plan is not just to fork an ES5-compatible tree, but to allow people to rewind the npm tree to an arbitrary branch mask based on any linting rule they like and append from there. If you want to narrow to only typescript+react packages with named exports for tree shaking, you could. I’m gonna do good old fashioned ES5 though, no promises allowed and no assignment in global scope)
the only thing wich is lacking right now is native support for it in the browsers
ES6 introduces way more syntax, making it much harder for beginners to learn.
Arrow functions make scope much harder to reason about, which makes closures more of an anti-pattern. In ES6 closures are one of a tiny number of scope patterns so you can actually use them.
Arrow functions cause bind to break in unpredictable ways.
Most other ES6 features are just syntactic sugar which offer no software engineering benefit and add a whole layer of conflicting code styles that one must constantly switch between, or else deal with constant pointless linting fixes if you are adhering to a consistent standard.
ES6 demands you use a transpiler which makes debugging flakier, and adds another place for bugs and maintenance work, in addition to often slowing he build down.
If I wanted deal with that much headache I’d just use typescript and at least get type checking in exchange for the syntax change and transpile step.
ES6 exists because some programmers never understood prototype and bind. And felt naming a function that is only called once was icky. Mostly former Ruby programmers. So they bolted a shitty Ruby onto JavaScript in order to get people to stop using prototype and bind, which are the heart of JavaScript’s control flow.
Basically the chest burster from Alien.
I think there's some pattern recognition routine in my head that convinces itself we're reading prose, based on the ratio of words to symbols, so it feels comfortable for a amateur hobbyist like me.
I know "bias towards keywords" isn't a functional language feature, but I think it is a nice UX.
Of course, then I learned about generators and decorators in Python... Those are fun too.
Generators are certainly "thinking in Python."
I love Rust as well, though I love it more as a concept than as an actual useful language. If only it weren't so freaking hard to get anything done in that language!
Because they have beautiful simplicity in the first case and interesting outcomes in the second. I continue to struggle to achieve expressiveness in either. Maybe before I die.
But my real favourite is awk. Because it was the first language I used with a hash structure and so let me explore writing code which did content addressed things like count uniques over stdin string streams from logs. All kinds of languages had functions and procedures and fancy schmancy if then else but having dynamically sized data which indexed off data.. that was electrifying. Perl had them after and I suspect that in part accounted for it's popularity. Every scripting language since has too.
Thinking in yield() generators goes naturally to composition of functions. That's about my limit.
So I've ended up back at VB after several years in other languages because it cuts out the cognitive load.
I might have said Haskell, except I have very little hands on experience with Haskell.
Elm is such a joy. Here are some reasons!
1. In the end, all your code is either functions or data!
2. There are only a few core concepts, and very little extra language features. There is zero implicit indirection. (E.g. macros or class inheritance.) As a result, it’s incredibly easy to reason about what the code is doing.
3. It’s incredibly straightforward to reason about what code is doing. Function bodies are just a single expression saying what the function returns. Functions are 100% “pure”; they don’t perform side effects, and when you pass in the same input you always always get the same output.
I work in Elixir day-to-day. Elixir’s great, but just today I spent hours digging through internals of Phoenix (the prevailing web framework) to implement a “low level” abstraction in our application. Trying to understand the flow of code in Phoenix was painful! (Because a lot of advanced language features are used that bring more layers of indirection.) Not so in Elm. There’s no objects, no classes, no inheritance hierarchies. Everything is way more concrete and clear from the get go.
are there any cases where elm was not the ideal solution but js was?
Its connection to Java brings a huge ecosystem of tools and libraries to the table, but if you don't need those, today Kotlin can also be used without Java or the JVM.
It has been my main language for work projects for over a year now and I still love the language.
It hits a real sweet spot for Enterprise coding, domain modeling, scientific computing, and cloud computing. It's the only way I'll touch legacy MS-ecosystem projects. The community is driven by open source and highly cross platform. It's also got type-checked scripting that makes 'plumbing languages' and utility scripts look second rate, for pragmatic day to day stuff, while maintaining complete access to the libraries and models of any of your systems.
Potent stuff for people whose technical decisions are regulated (or even just subject to Enterprise Thinking by Important People).
It's hard to find a problem that only has one Python library that solves it. Most of the time you have a dozen, and half of those are maintained better than I'd ever expect.
See http://t3x.org if you want to have a look at Klong, T3X, and all the other languages I have implemented or invented.
Haskell is now the current inspiration for many object-oriented languages like C# and Java:
http://wadler.blogspot.co.uk/2012/09/brian-goetz-on-future-o...
I find Haskell clears up your thinking a lot, but it's really not great for production work. Go on the other hand is extremely great for prod work
I started to look into Elm and might fall in love with it soon enough, if so I'll try my best to make my coworker love it too :)
Tldr: OCaml in my dreams, Typescript in reality, probably soon to be replaced by Elm
It has a beautiful clean syntax, which is as concise as I can imagine that a human readable language could get to giving instructions to a computer.
My favorite "for fun" languages are TCL and Ada. TCL because of its simplicity and elegance, Ada because of its type system, oop model, and compiler.
All begins with the primitive infinite sequences and the language's means of combination (specified with decimal digits)
---universe begin---
sequence 01: 0 1 2 3 4 5 ...
sequence 03: 1 2 3 4 5 6 ...
sequence 05: 2 3 4 5 6 7 ...
sequence 07: 3 4 5 6 7 8 ...
...
---universe end---
0105: count by two
---universe begin---
sequence 01: 0 1 2 3 4 5 ...
sequence 02: 0 2 4 6 8 10...
sequence 03: 1 2 3 4 5 6 ...
sequence 05: 2 3 4 5 6 7 ...
sequence 06: 1 3 5 7 9 11 ...
sequence 07: 3 4 5 6 7 8 ...
...
---universe end---
01030501: set up some cycles
---universe begin---
sequence 01: 0 1 2 3 4 5 ...
sequence 02: 0 2 4 6 8 10...
sequence 03: 1 2 3 4 5 6 ...
sequence 04: 0 1 2 0 1 2 ...
sequence 05: 2 3 4 5 6 7 ...
sequence 06: 1 3 5 7 9 11 ...
sequence 07: 3 4 5 6 7 8 ...
...
---universe end---
Please note that as the universe grows we always leave space for more sequences by skipping every other sequence designation.
What makes this language useful is that with very little effort any two arbitrary infinite sequences can be defined. As a consequence any mathematical relation is easily defined as a mapping from members of one sequence to the corresponding members of the other sequence.
I will briefly describe the language's means of combination. Writing a sequence designation one next to another will form new sequences by pulling out corresponding members. But all sequences are infinite so after the last designated sequence is visited the member value is used to select the possibly new member in the first designated sequence. Digits that are not able to be confused with sequence designations specify the three other primary means of combination. They are "cons", "car", "cdr". With a proper understanding of their use one can build arbitrary sequences. I will just say that "cons", "car", and "cdr" are used to combine entire sequences which is logically equivalent to combining corresponding members of those sequences.
In the code above I write "0105". The "01" is a sequence designation. The "05" is a sequence designation.
I define an infinite number of new sequences twice over in the example above. Between "---universe begin---" and "---universe end---" is listed the state of the universe. After inspecting the current state of the universe one can add new sequences with numeric codes as I have attempted to describe. The example above shows two iterations of this process. In each case an infinite number of sequences is added. So really your program will describe an infinite sequence of infinite sequences. And, if you never stop programming, then you are actively directing an infinite sequence of infinite sequences of infinite sequences!
The purpose of the language is to be "general purpose". Any programming problem can be modeled with this language. Because a number represents anything at all, I would not hesitate to use the language anywhere I have need for an algorithm. Input transformed to number is manipulated by algorithm then presented to the user as output. A gui is typically used to control this process.
Impressively, it is possible to write relations with very little knowledge of specific algorithms. For instance, you may know how to square a number but be totally ignorant of methods to find the inverse function (the square root). Not a problem - you already know enough to direct the computer to take square roots. This might seem magical. It certainly is magnificent, but there is no magic involved. It all has to do with the design of the language.
select this from that where something is true
That’s the core of everything you do.
I could write all day about what a mess it can become, and how awful debugging is. But I still enjoy it
I'm still amazed how much stuff is build in and don't need a plug-in or extension or need you to write your own function...