Live data from Hacker News

ES7 Proposal: The Pipeline Operator

github.com

61–70 of 78 posts

Re: ES7 Proposal: The Pipeline Operator

#61
post #52

That's beautiful, the linear pipeline better matches your intuition about the computation than the nested functions. Can we have this in C# 7? :)

This essentially exists - extension methods.

Extension methods only apply to instances and they must be declared explicitly.

This syntax can be used anywhere as long as the types signatures of the functions are conducive to the chaining.

Re: ES7 Proposal: The Pipeline Operator

#62

In concatenative languages, this style of composition is the norm, and it does indeed work well for many tasks: http://concatenative.org/wiki/view/Pipeline%20style

It is available in JS too:

    function double(str) {
      return str+', '+str;
    }
    function ucase(str) {
      return str.slice(0,1).toUpperCase()+ str.slice(1);
    }
    function exclamation(str) {
      return str+"!";
    }
    
    var _="hello";
    _ = double(_);
    _ = ucase(_);
    // _ = foo(_);
    _ = exclamation(_);
    
    console.log(_); // Hello, hello!
    
    function pipe() {
      var functions=[];
      for(var i=0; i

Re: ES7 Proposal: The Pipeline Operator

#64
post #59

Earlier quoted context omitted.

js objects are mutable; utliliy libraries like underscore, lodash, jquery, do not provide purity guarantees, they export impure functions that mutate objects (e.g. https://lodash.com/docs#merge ). When we start leaning heavily on function composition to build our abstractions, we simply must have purity guarantees for everyday utilities or everything falls apart. So to go "full-on functional" in javascript means we n…

So we need an (a) method to freeze object and it children, (b) to indicate that function will accept and/or return only read-only objects. Reserved "const" keyword is perfect for that.

That's unfortunately not what es6 const does - const is about re-assignment, not about immutability. (Though you can implement immutability in terms of non-re-assinment if it is const-all-the-way-down, which javascript objects aren't.) And you still need to re-write all the ecosystem to work with immutable objects.

Re: ES7 Proposal: The Pipeline Operator

#65
post #26

Can we just put more focus on sweet.js so we can do this kind of in a library with standard build tooling? http://sweetjs.org/ There's a lot more operators than |> that you would want. Clojure commonly uses ->, ->>, as->, etc. It should be done in a library if it is done at all. Also, going full-on functional in javascript is going to end badly, javascript simply wasn't designed for it. If you go down this path in re…

Can you elaborate on the rough seams between JavaScript and "full on functional"? I'm not a believer in the FP vs. OO religion, and have historically been skeptical of the bind operator. That said, I think that both composition via objects and composition via functions have their place. The pipeline operator attempts to make composition via functions more readable (left-to-right instead of right-to-left) and unless y…

Briefly, you can look at it through the prism of equality.

In javascript, 1 === 1, and "foo" === "foo". However, [] !== [] and {} !== {}. This is because in Javascript, like in Java, there is a distinction between value types (essentially, simple primitive values like numbers and strings) and reference types (collections - arrays and objects). When you assign an array to a variable, you are actually pointing the variable to a reference to the array. As a mutable data structure, its identity is more important than its value: it is expected that you shall be calling push, etc, and thus changing its value in place.

In Clojure (for example), (= 1 1) and (= "foo" "foo") and (= [] []) and (= {} {}). Because Clojure's data structures are immutable, the idea of checking for identity is almost meaningless (although you can, with the identical? function). In an FP style, with generic but immutable data structures, we are more interested in value equality, since we are not concerned so much with objects with a long lifecycle over which the values of their fields may change.

Javascript is in an odd position - it has enough features for both traditional OO and functional programming styles to be possible, but the two do not easily co-exist. Compromises are necessary. So, if our program is composed of mostly pure functions operating on generic data structures, we must do a lot of defensive copying, and use library functions for deep equality, because the data structures are not designed for this usage.

This is not to say it's infeasible to program in this way in Javascript: it is, and I try to. But a language designed from the ground up for functional programming will point you more enthusiastically in that direction than JS does.

On topic: like the syntax!

Re: ES7 Proposal: The Pipeline Operator

#66
post #40
post #8

What's so painful about just doing `exclaim(capitalize(doubleSay("hello")));`? Why introduce needless syntactic sugar that'll only confuse people about how UNIX pipes work?

it's very common in javascript to have chained methods, to be able to do things like _(array) .compact() .map(function(x) { return x * x; }) .filter(function(x) { return x > 100; }).value() (example from underscore/lodash) The problem with this is to be able to add a custom function to this pipeline, you have to extend the prototype of the library with your own functions, or re-implement it. Extending the prototype i…

> The problem with this is to be able to add a custom function to this pipeline, you have to extend the prototype of the library with your own functions, or re-implement it.

That's exactly what transducers try to solve, and fortunately they do exist for js (http://jlongster.com/Transducers.js--A-JavaScript-Library-fo...) where processing of individual elements is separated from plumbing, so you can add your own custom computation in the chain. It even has pretty good performances (http://jlongster.com/Transducers.js-Round-2-with-Benchmarks), all with the standard data structures !

Of course transducers are useful only when you want to transform data, not when you want to act on them in the chain.

Re: ES7 Proposal: The Pipeline Operator

#67
post #52

Earlier quoted context omitted.

This essentially exists - extension methods.

Extension methods only apply to instances and they must be declared explicitly. This syntax can be used anywhere as long as the types signatures of the functions are conducive to the chaining.

Not sure what you mean with applying only to instances, in which case couldn't you use an extension method? If you own the code making a function an extension method seems not a big deal. If you want to invoke a static function you don't own the code for then you could have a generic wrapper extension method which admittedly would probably look rather clumsy and nullify the desired gain in readability.

Re: ES7 Proposal: The Pipeline Operator

#68
post #43

Earlier quoted context omitted.

Can't speak for nim, but Clojure has a near-exact feature which is used all over the place, the thread-first and thread-last macros. Example: (defn do-stuff [params-map] (-> (build-object params-map) (do-thing-with-object) (extract-thing) (format-thing))) I'm not sure why you'd choose Clojure to get away from things like |>.

Elixir has this exact feature. I'm sure it's not the first language to either.

F#/OCaml too, probably all the ML variants actually.

Re: ES7 Proposal: The Pipeline Operator

#69
post #65
post #26

Earlier quoted context omitted.

Can you elaborate on the rough seams between JavaScript and "full on functional"? I'm not a believer in the FP vs. OO religion, and have historically been skeptical of the bind operator. That said, I think that both composition via objects and composition via functions have their place. The pipeline operator attempts to make composition via functions more readable (left-to-right instead of right-to-left) and unless y…

Briefly, you can look at it through the prism of equality. In javascript, 1 === 1, and "foo" === "foo". However, [] !== [] and {} !== {}. This is because in Javascript, like in Java, there is a distinction between value types (essentially, simple primitive values like numbers and strings) and reference types (collections - arrays and objects). When you assign an array to a variable, you are actually pointing the vari…

(you're replying to the guy who wrote Ember.js)

Re: ES7 Proposal: The Pipeline Operator

#70
post #35
post #7

I feel like that just confuses things for no good reason. It's no fewer characters than parens but provides as I see it less clarity.

How it's "less clarity"? What happens is much easier to read if you know what the operator means. The only way the old way has more clarity is in the "we are already familiar with it" way. In any other way, this method trumps it.

It's much less clear than the F# and Elixir versions of |> are, so if you've used those languages this feels confusing looking. It would be nice to introduce |> into Javascript while keeping it just as understandable as it is in every other language that already has it.
Post reply on HN