Ask HN: Great programming language features, other languages should steal?
You cannot be fluent in all programming languages. But this also makes you blind for language features a particular language really got right, or killer libraries that are just amazing. Which are these widely unknown features, that you only get to know, when working with a language and its ecosystem?
Example: I'm coming from Scala. Starting to develop a Flutter app with Dart, made me realize how great and safe the serialization ecosystem in Scala is. You can serialize types (and type hierarchies) with a convenient syntax that is completely decoupled from the type itself, while high-performance serialization code is generated at compile-time via macros. Libraries include: https://circe.github.io/circe/ https://github.com/suzaku-io/boopickle
43 comments
[ 4.1 ms ] story [ 112 ms ] thread2. Currying like in Haskell.
2. scoped threading a la kotlin and by using certain libraries, rust to a degree.
3. structs / records (i feel bad putting this since every language but java seems to have it).
4. macros of some kind
5. type inference
6. enums a la rust / sealed types in kotlin which are needed for pattern matching afaik
Other than that? Delimited continuations. Guile-fibers, a parallel concurrent ML (which I would describe as a generalisation of go's concurrency model) for guile scheme is implemented using them as a scheme-only library. No low level voodoo. Just straight forward scheme.
* Higher-kinded types. Can a List<Int> and a Stream<Int> both be considered a T<Int> ?
* Differentiate between functions with and without effects.
2. There was one new language that I don't remember the name, its data structures automatically turned to thread-safe upon concurrent access. That's smart. I wish all languages do that. Less data structure names people have to remember.
3. The compiler can cross-compiles to many different architectures similar to Go or Zig. This makes deployment story much simpler.
4. The compiler produces single binary by default. This also makes deployment story simpler.
5. This is year 2020. Every language must have an event loop so that they can have async I/O routines. Preferably in the form of CSP (green threads + channels).
As you can see I care about the ergonomics and tooling outside the language itself.
But in lisp it's more than just a syntax trick that only works for a few predefined cases.
Complete sample:
This is almost certainly because RMS is a Lisp hacker. I.e. why GCC uses Lisp notations internally and functions with "mapcar" in the name and such.I discovered it by accident sometime in 1993. I wanted the value of the last expression in a braced block. Maybe it can forced into an expression if you just put parentheses on it? By golly, the intuition worked.
Mainly, it is used in writing macros. Speaking of which:
Go tries to be a syntax minimalist so that the writers can make what's there the best rather than building the world of fancy new PL features. It also means there are fewer days of doing the same thing and most people's code looks the same. <- this is such a difference maker
[1] https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node317.html
[2] http://gigamonkeys.com/book/beyond-exception-handling-condit...
https://www.youtube.com/watch?v=kc9HwsxE1OY
Julia's multiple dispatch semantics were designed around having a JIT compiler, and it's JIT compiler design was designed around having multiple dispatch, and this tight integration let us be really good at de-virtualizing the dispatch, removing the hefty performance pentalty.
This is why even basic arithmetic operations like +, * and whatnot are able to be generic functions (with a gigantic number of methods, 184 for + and 364 for * currently just in Base and LinearAlgebra!) without any runtime performance compromise.
By contrast, Nim for instance just removed multiple dispatch in their 1.0 release because nobody was using it due to being so slow.
On the flip side, I think we have some dynamic metaprogramming magic of our own that might even impress some lispers such as IRTools.jl's dynamos or Cassette.jl's overdubing.
I'm not aware of many languages which do that other than Kotlin.
Totally agree with you on this one, but I'm not sure I'd go so far as to say that they're a defining feature of Python, more of functional languages, from which Python has borrowed a thing or two.
E.g. is_prime(1234) => prime?(1234), append_inplace(l, e) => append!(l, e), array_equal(a, b) => array=(a, b), midi_to_mp3(a) => midi>mp3(a), reciprocal(a) => ^-1(a)
Lisp can do some of it but not "()" or (I think) "`';"
There is more than one way to escape: vertical bars or backslashes:
https://kotlinlang.org/docs/reference/extensions.html
I personally love it for when I have different data classes for different layers of the application (REST objects vs. controller level objects vs. Database objects) and need to convert between them. I simply just add an extension to one layer's data object to convert it to the other layer's type