
Interesting features from various modern programming languages - mmphosis
https://medium.com/@kasperpeulen/10-features-from-various-modern-languages-that-i-would-like-to-see-in-any-programming-language-f2a4a8ee6727
======
vbuwivbiu
In Clojure:

1) pipeline operator: thread macro

2) pattern-matching: multimethods, core.match

3) reactive programming: Reagent/re-frame, atoms, core.async

4) implicit name 'it': %

5) destructuring: destructuring

6) cascade: .. macro

7) if: if

8) try: try

9) currying: currying

10) method extensions: protocols

~~~
acangiano
The advantages of a small, extremely flexible language.

------
DonaldPShimoda
Some thoughts as I read through this (I'm far from an expert in PL, so...
forgive me any naivety, please).

I can't decide if I like the pipeline operator (1). Is it really better?
Perhaps I'm just used to chaining multiple function calls together.

Pattern-matching (2) is my favorite language feature, or at least it's pretty
high up there. Super useful. I always wish I had it in Python (my go-to
language most of the time).

Not sure I really "get" reactive programming (3).

With regard to implicit names (4), I think I actually prefer writing lambdas
with my own variable names, and I particularly like Haskell's syntax for it.

Even Scala's usage of the underscore seems a little better than this "it"
business, if only because the underscore doesn't see much use elsewhere so
it's an indicator that "Hey, something's going on here!"

But using a regular-looking variable name seems a bit unintuitive for somebody
unfamiliar. Though I suppose they may not be the people for whom this sort of
code is written.

Isn't destructuring (5) just an effect of ADTs? Which are also what produce
(2) pattern-matching, so perhaps really what the author enjoys is ADTs. Or
maybe I don't know things.

No strong feelings on (6). Maybe I'd need more exposure.

Are if-expressions (7) actually on this list? In the comments they practically
suggest that the ternary conditional is the "regular" way of handling such
things, which is... silly. The rest of this list seemed interesting, so I'm
confused why these make the cut. Perhaps the author was just being cheeky.

Try-expression (8) are nice and all, but the best is when you can eschew them
completely. I like the way optionals are wrapped into so much in Swift; almost
makes obsolete all the try-expressions (except for certain cases, such as
whenever you call into an older Obj-C library or something).

Definitely a fan of auto-currying (9).

Is method extension (10) similar to overriding the "magic" double-underscore
methods in Python, such as `__add__`? That definitely seems useful.

~~~
always_good
One issue with auto-currying is that, afaict, it prevents arity overloading.
For example, I find this pretty silly: [http://package.elm-
lang.org/packages/elm-lang/core/5.1.1/Jso...](http://package.elm-
lang.org/packages/elm-lang/core/5.1.1/Json-Decode#map6)

One feature that always impressed me is how Kotlin has bring-your-own-chaining
methods defined on everything.

    
    
        request(url).let { req ->
            req.setQuery(mapOf("a" to 42))
        }.let {
            it.body = "foo"
        }.apply { // `this` is implicit receiver inside apply() 
            send() 
        }
    

Not the best example of how it's useful because I'm rusty, but it's nice to
just chain your own transformations on anything. I miss it all the time.

~~~
yorwba
You can do arity overloading with curried functions if you allow overloading
the function application operator itself. E.g. if _f_ is of type _A → B_ and
_a_ is of type _Decoder A_ then _map f a_ is of type _Decoder B_ and in the
special case where _B_ is a function type _C → D_ , that _Decoder B = Decoder
(C → D)_ can be applied to a value _c_ of type _Decoder C_ making _map f a c_
a _Decoder D_.

Caveat: I'm not aware of any language that actually does this, likely because
redefining the core syntax of function application would be _so_ easy to
abuse.

EDIT: Removed my Haskell example, because I think I got it wrong.

------
tigershark
He can't find the documentation for the pipeline operator. And he posted
examples from ReasonML rather than F# and OCaml. For reference this is the
documentation for the pipeline operator in F#:
[https://msdn.microsoft.com/visualfsharpdocs/conceptual/opera...](https://msdn.microsoft.com/visualfsharpdocs/conceptual/operators.%5b-h%5d-%5d%5b%27t1%2c%27u%5d-function-%5bfsharp%5d)
It's kind of sad that people nowadays know only JavaScript and languages from
the web ignoring the original language from where the syntax come from. I
would not be surprised if he posted some purescript instead of Haskell. As per
the "modern" languages in the title the author has no idea about what he is
speaking about. OCaml is 21 years old, just 1 year younger than Java, I would
not call it a "modern" language. But if someone thinks that the code he posted
exists only in ReasonML than _that one_ can be defined a modern language. I
rarely criticise blog post, but this one is just not well written and the
author has no idea about this subject.

~~~
igravious
> but this one is just not well written and the author has no idea about this
> subject.

Rubbish. The examples are good. The author comes across as enthusiastic. The
writing style is fine and engaging. A couple of the examples are from a modern
variant of an older language but so what? That small oversight and you
completely bash the effort?

You could have said,

"The writing didn't do it for me and the author has more to learn about the
subject" but you came out with the big stick instead. You come across like a
typical elitist functional programmer. Blah, blah, blah, Lisp had that _forty_
years ago, lame!

I thought the language features were interesting. I'd read up on Kotlin but
overlooked the _it_ keyword, I'd love if Ruby got that. In fact, I was trying
to figure out which features Ruby has the whole time. Ruby blocks (closures?)
are cool with the _||_ operator but having a default _it_ keyword, we should
totally steal that. In total I think Ruby has #5 Destructuring, #7 If
Expressions, #10 Method Extensions (called Open Classes in Ruby I think) –
correct me if I'm wrong. Ruby kind of does pattern matching with the _case_
statement/expression. The Pipeline Operator looks cool. I don't think Ruby has
anything like the Cascade operator either.

~~~
tigershark
I'm sorry, I don't know what are you used to read, but writing an example and
after that just pointing at the documentation (or at something completely
unrelated like in the first example) is not an example of good writing. You
are forced to follow the link and it breaks your flow. The it keyword is also
not original in kotlin. Groovy has it for example. The author is just getting
random features that have been around for decades mistakenly believing that
some modern language introduced it.

Your attack is completely non-sense, I don't know lisp and I don't like it.
Furthermore in my day to day job I write only OO code (sadly). And I certainly
don't think that my post is rubbish given that I explained the reasons for my
criticism.

~~~
zelos
To be fair, he doesn't explicitly say "these features were invented in
Kotlin/Dart/...". He just says he hadn't read about them before.

------
copx
How is the pipeline operator better than bog standard method chaining you have
in any OO language?

    
    
      let result = "hello"
        |> doubleSay
        |> capitalize
        |> exclaim;
    

vs.

    
    
      result = "hello".doubleSay().capitalize().exclaim()
    

I certainly prefer method chaining here.

~~~
bunderbunder
It's not a replacement for method chaining, and can't even be used for that
purpose. It's for rearranging the relative position of a function's arguments.
In pseudocode, it's defined like:

    
    
      x |> f  ->. f(x)
    

So, applying that, it would let you transform something like

    
    
      exclaim(capitalize(doubleSay("hello")))
    

to your first example. But it can't do anything with the 2nd example, because
those are not functions with arguments, they're all 0-arity method calls.

More generally, I don't think this operator makes much sense in a language
that's mostly object-oriented. I made one in Scala a while back and toyed with
it, but even there it's pretty useless because the libraries follow a very
object-oriented coding style. I've really only seen it shine in a language
that has strong ML roots and tends to stick to them.

~~~
tom_mellior
> those are not functions with arguments, they're all 0-arity method calls

In other words, they are 1-argument function calls. The "this"/"self"
parameter is implicit in many languages, but otherwise it's not different from
a normal function parameter. In the "method chaining" version of the example,
each method call returns a (reference to) a temporary object which is passed
as the next method call's "this" parameter.

~~~
bunderbunder
In most languages, that's an implementation detail that is hidden by the
compiler, and not a part of the semantics of the language itself.

More specifically, if the language won't allow me to do both:

    
    
      foo.method(x)
    

and

    
    
      method(foo, x)
    

and have them behave the same way, then I submit that, regardless of what's
going on behind the curtain, a n-arity method is not really the same thing as
a (n+1)-arity function in that language.

~~~
kd5bjo
Python is pretty close to this. Assuming that foo is an instance of class Bar,

foo.method(x)

Is equivalent[1] to

Bar.method(foo, x)

[1] in the absence of monkey patching on foo

------
misterdata
Also interesting: goroutines (Go), borrowing semantics (Rust), various forms
of concurrency (e.g. blocks in ObjC/Swift with GCD, mutex closures, futures,
etc.).

------
Ajedi32
I love the way this is presented. I strongly prefer these clean, readable
examples to long explanations of each feature.

~~~
stefanpie
I finally understood a little of what currying meant after seeing it on HN
once or twice in the past week

------
hackerfromthefu
All these new language features are good taken on their own, but in the big
picture many languages are getting relentlessly more complex.

Many are getting to the point the complexity encourages different programming
styles within one language that while syntactically valid can be so different
that other programmers can't easily understand them (such as C++), which is a
problem for delivering business value.

Cohesiveness and simplicity is a feature, that delivers real and significant
business value.

~~~
acangiano
I tend to agree. At the two extreme ends of the spectrum I'd place Go and
Scala. Go very simple, Scala very complex.

What happens in practice is that Go code looks all the same, it's easy to
program in, reason about, and train new programmers in. It's not that
expressive or flexible, but bad Go code really jumps at you.

Scala tries to be all things. The result is that it's not obvious what great
Scala code is supposed to look like. Successful Scala teams tend to stick to a
subset of the language, usually the more functional side.

I think languages like Clojure, Elixir, F#, and Kotlin offer a happier middle
ground. Plenty powerful but not as cognitively taxing.

------
hackerfromthefu
The cascade operator looks like an Object Pascal construct that originated
decades ago, called 'using' in that language. e.g.

using myPoint .x = 1 .y = 1 end

a bit rusty on the syntax but that was the basics of it!

~~~
calvinr
It's also very similar to the with keyword in Visual Basic

With myPoint

    
    
      .x = 1
    
      .y = 1
    

End With

------
thriftwy
Most of this is syntactic sugar, and one widely available in Haskell, lisps
and even mainstream languages like Ruby.

------
anon335dtzbvc
Can i have implicit name of a single parameter in javascript via babel
extension?

~~~
thomasfoster96
It would be possible to do, but it hasn’t been proposed as an ECMAScript
feature nor do I know of any plugins that implement it, so you’d have to write
the plugin yourself.

------
singularity2001
Pipeline operator is often superfluous if proper object oriented programming
is used. "hello".capitalize (ruby style)

"implicit 'it'" is my favorite: strings.filter{ it.length == 5 }

And Cascade operator buttons..hidden=true

Automatic currying is dangerous

Method extensions are not 'new' but nice

~~~
wiml
The "implicit it" is called anaphor in Lisp (though using that term for a
programming language feature I think only goes back to the 1990s; the idea
itself is older).

(The word "anaphor" here comes from the study of grammar in natural
languages.)

~~~
kazinator
The usage goes back to Paul Graham and his macros with the implicit _it_.

Which appear in Arc.

In which this site is developed.

