One thing that comes to mind is Ruby's macro-style methods:
class BankAccount < Account
attr_accessor :balance
belongs_to :customer
end
What's something your favorite language has that others don't? Or something from a language you tried out that one time and immediately missed it in other languages?
Latest comments (32)
Having worked mostly with Elm, Python and Go lately, there's a LOT of things I miss when working with other languages.
Good and clear ecosystems - Elm's automatic versioning is ingenious, Python has a pretty solid selection of libraries and with
Pipenv
it's even a bit better than standard, and Go is getting pretty solid as well. There's also no excessive use of microlibraries that add one basic function that everyone depends on multiple times in their dependency tree.Joy of development - constantly cursing why the language and it's standard libraries are missing very basic things, debugging being a pain, the runtime environments or compilers not catching super obvious errors (ever done a
setTimeout(callback(), 1000)
and realized that JS engines don't throw exceptions whensetTimeout
callback isundefined
?), are just not things that happen a lot with these languagesClear standards -
gofmt
, PEP-8, and similar just save so much headaches. IDEs are configured by default to have one shortcut to reformat the whole file to the language standard, or even just reformat on save, etc. .. saves so much hassle overallGood concurrency model - Go's channels and goroutines are such an awesome thing to work with, and it always pisses me off when I have to work with any other style because they take so much more work to make reliable
Clear frontend application model - with Elm you get so much certainty over how things are going to work due to how the language is designed. You avoid whole classes of problems because you just always build your applications in a specific way, and it's the right way for at least most cases.
The flexibility - there's almost never a situation where I think "I wonder if I can do this in Python" and the answer is "no". With the whole language being built with well done duck typing instead of e.g. unpredictable type juggling, it's a breeze to do so many things. Similarly with Go, the interface system allows me to customize things a lot more than I would ever have expected from such a low level language.
These are just the things that come to mind in the first few minutes.
I think this is more of an underutilized features rather than an uncommon one, but I really like Extension Methods. They allow you to "attach" a method to a class that you otherwise can't or don't want to modify.
For example, rather than:
You can write:
In Xojo you'd do this with the Extends keyword in the global method definition:
Switches and cases. I love them. But when I tried out Python, I was really surprised that it didn’t have them, especially since the C# syntax looks a lot like it could be Python. For example, the Python equivelant of
is currently
I know that both PEP 275 and PEP 3103 have been rejected, but I have high hopes that a new one is created and accepted.
If you are doing simple task which involves just one statement, instead of using
if-elif
in Python, you may implement switch statements more elegantly using dictionary.For example:
Sample Run:
Above function will return "value" function corresponding to "key". If "key" not found in dictionary, it will return value as "default_value", just like default in
switch
statements.That's not really a switch statement, but more of a dictionary abstraction. In a real switch, you can run code based on the value. If I were to modify your snippet, I'd have to get busy with functions and stuff.
Maybe it has something to do with having "one way to do it". I never understood the hate for switch/case statements though. It's a little counter-intuitive how they fall through by default in C/C#/C++, but it's still a common thing to want to map a set of possible values to a set of possible actions.
Or return values! Like in Ruby:
There's another thing I like from Ruby and Lisp: you don't have to explicitly return, you can just have the return value be whatever the last expression was.
Yeah you’re probably right.
pointers - C
templates - C++
decorator syntax - Python
pipes - bash
Perl 6 grammars
They go many steps further than simple regexes, organizing and systematizing them. Plus they are classes than can use roles, can be subclassed, or have class variables. Here's an article I wrote about them.
In Clojure, I really like the
threading macro
.Imagine we have a string
" I will be a url slug "
, and we want to transform it into a valid "url". Let's build aslugify
function to do this transformation.Here we have:
Another solution is to use the threading macro. Basically we can compose functions using the -> operator.
Beautiful!
PS. another solution is to compose all function using
comp
function :)PS2. I wrote a post about Functional Programming with Clojure
It's nice not having to work backwards:
instead of
I once wrote something to let you do this in Python:
Python had the idea that methods are just functions (hence having an explicit
self
parameter), it just didn't take it far enough.Monads. Seriously! They make composing function so easy: For example you parse a number for a string the user types in (which might fail if the string is not a number), then you want to index a list at that position (which could fail because the list might be shorter) and then you want to print the element at that position out or an error if a previous step failed. In Haskell this looks like this (I added the type signatures of the functions used on top):
Here you see the same function (
>=>
, which has typeMonad m => (a -> m b) -> (b -> m c) -> (a -> m c)
btw, so it just composes two monadic functions) used for two completely different contexts: First for theMaybe
type and then for doingIO
. This is the beauty of Monads (and similar type classes). They provide a unified interface over a great range of types. Once you know how to use Monads in general, you can use it on any type that is a Monad. No more consulting the specific API of the library. Everything has the same API!Ahahahaha
I miss Swift's strongly typed enums with associated values a lot in other languages (Go, Python etc.).
From the textbook:
Thanks for the nightmarish flashbacks! 😂😱
Python's list comprehensions! The syntax is super elegant, and they are really performant.
In JavaScript, to filter values, you would do something like this:
in Python, you would use a list comprehension
You can also transform all the elements in a list (similar to a map in JavaScript):
List comprehension is awesome!
Pattern matching as done in ML languages.
I think it's a much more elegant way to handle end conditions and special cases than
if
statements and it makes the code much easier to reason about.It is also awesome when used in conjunction with union types.
If I had ever understood lisp's macros I would probably mention them here too.
Pattern matching, really loved it when I came across it in Erlang. Should brush up on declarative languages
Deterministic object destruction is probably my favorite feature of C++ that is found in only a select few other languages. When execution leaves a function or any other scope, be it regularly or through an exception, all local objects get destroyed and their destructors executed. Not eventually when a garbage connector feels like cleaning up some leftovers but immediately. This includes the automatic destruction of that class' member objects.
That means there's also no need for
finally
: cleaning up all those file handles, memory allocations and network sockets and painting the sky blue again is done automagically by the destructors of properly written filestreams, smart pointers, socket classes and temporary sky blackeners.String interpolation.
Two things I think are really powerful in F# that are not found in most languages.
Union types are a way to represent one of multiple different possibilities. It is a bit like an enum type that can have extra data with it.
Most languages have a way you can kinda-sorta define these. One common method in OO is an abstract base class with shallow inheritance. But it is a lot of code overhead versus the concise definition above. And it is also not particularly idiomatic to OO. People probably wouldn't bat an eye at using
case
on an enum, but type checking for a derived class is often considered a code smell.You can also represent these choices as nullable fields in a single class, but then you have to write a bit of code to control access and protect against the case where none or multiple of them are set at once. Doable, but annoying enough that people usually don't.
Value equality by default is very nice for testing. It means I can do things like this:
If the
actual
has the same values asexpected
(1 and "One" here), then it will return true. And it works for union types too. In most languages, these things have reference equality by default. So the last line would only return true ifactual
andexpected
were pointing to the same memory location, which is not super helpful. You can usually get value equality in any language, but it might be a pain. In C# for example, you can override the default implementations ofGetHashCode
andEquals
to get value equality. It adds an extra 8+ lines of code to every class definition (and each field adds more lines of code potentially). I believe a lot of people use tools to add them in automatically and then code folding to hide them. Or just manually check for equality when needed.And I could go on: no nulls, immutability by default, pattern matching, composable asyncs, sequences, etc. Then I need to go fix something in our VB code base, and it's 😬😬😬. Well, one thing VB has that most others don't is XML literals. So there's that.
I don't like when languages call abstract data types "union". Because it is technically not true. They are disjoint unions, which makes them nice to use. The only language that I know that has actual union types is typescript.
F# calls them discriminated unions, technically. For the purposes of my comment I called them union types to keep it conceptually simple. The extra adjective "disjoint" or "discriminated" is more technically correct, but for many people it automatically biases them to react with "too complex; didn't read". When really it is a simple concept.