reason icon indicating copy to clipboard operation
reason copied to clipboard

Suggestion: Change Js.log to a => a

Open wpcarro opened this issue 7 years ago • 7 comments

Some functional programming languages model their logging functions as a => a instead of as a => unit. Elixir, is a great example of this with its IO.inspect function.

I think modeling the Js.log function in ReasonML like this would improve the developer experience, since it would allow developers to inject Js.log in their pipelines without disturbing the data flow.

For example...

doSomething() |> Js.log |> doSomethingElse() |> Js.log

...currently the intermittent Js.log calls would break the pipeline. Pipelines are just one use-case, and there are a few others that benefit from the update type signature.

If an analogous function like this already exists, please forgive my ignorance.

wpcarro avatar Jan 23 '18 20:01 wpcarro

I like this idea, but it would break code which expects log to return a unit, and it's quite trivial to define that function yourself moreover

ncthbrt avatar Jan 23 '18 20:01 ncthbrt

@ncthbrt You're right it's trivial to define this function. I'm arguing that Reason should support it at the stdlib level, so that it's more off-the-shelf. It may sound like a small difference, but these small differences end up making more of a difference in my experience than the attention they're originally given.

Whether this means releasing an updated, breaking-changes version or supporting something like a top-level inspect/1 function is less important to me. Prioritizing developer experience is the priority with which I'm most interested.

wpcarro avatar Jan 23 '18 20:01 wpcarro

" I'm arguing that Reason should support it at the stdlib level"

That would be a good suggestion for BuckleScript - and @bobzhang is actively working on the design of standard available libraries. You may wish to file an issue on the bucklescript repo.

jordwalke avatar Jan 23 '18 21:01 jordwalke

Btw we should document it more clearly, but Js.* don't have wrapping cost. Js.log is a straightforward console.log, for example.

We can always build higher-level wrappers if needed, but things under Js are the basic, performant primitives

chenglou avatar Jan 31 '18 05:01 chenglou

When I need this functionality, I just do the following:

let log = x => { Js.log(x); x };
doSomething() |> log |> doSomethingElse |> log |> ignore;

ckknight avatar Mar 23 '18 04:03 ckknight

relevant to https://github.com/BuckleScript/bucklescript/issues/2664

some rough ideas: in the new pipe syntax, it could be:

doSomething () 
|.  begin 
       Js.log ; 
      doSomethingElse
    end
|. Js.log

bobzhang avatar Mar 23 '18 09:03 bobzhang

What about using something like tap (not included in Belt, but standard in a lot of libs)?

As in:

open Fn;

doSomething() -> tap(Js.log) -> doSomethingElse ->tap(Js.log);

Or even log = Fn.tap(_, Js.log)?

hoichi avatar Dec 04 '19 11:12 hoichi