4 ms·
There are some nice bits in here. tap() and then() are fairly minor, but very nice quality-of-life additions. The work on numerical, livebook, Mix.install etc
by svrtknst 5y ago
There are some nice bits in here.
tap() and then() are fairly minor, but very nice quality-of-life additions.
The work on numerical, livebook, Mix.install etc are healthy steps to take.
Nice work.
- dmitriid 5y agoI wish they'd instead fix the compiler to not require .then But in absence of that this is a huge QoL improvement. tap though... OMG yes!
- klibertp 5y agoI was very, very disappointed that the `tap` macro has nothing to do with pattern_tap: https://github.com/mgwidmann/elixir-pattern_tap https://github.com/mgwidmann/elixir-pattern_tap Basically, in Elixir pipelines are not very friendly to simple destructuring: if a call at the beginning of the pipeline returns a tuple of `{:ok, result}`, you can't use either of shortcut syntaxes for lambdas (&Mod.fun/arity and &Mod.fun(&1)), you have to use `fn` and destructure in its head. pattern_tap solves this quite elegantly, but I was told that it's a "non-standard macro that people don't know, so it shouldn't be used"... So when I saw `tap` in Kernel, I though that maybe it's similar at least... unfortunately, it's not similar at all, and now the global identifier `tap` is taken, which made the situation even worse :(
- shakow 5y ago> if a call at the beginning of the pipeline returns a tuple of `{:ok, result}` In my understanding, pipeline are mostly reserved for “unfailable” operations operating on raw data; whereas the where/else/do macro is more oriented towards errors handling; would it work better in your case?
- klibertp 5y agoI think you mean `with`, not `where`? Yes, it helps a bit in some cases, but it's not a replacement for a pipeline - mainly because you'd need to name your intermediate results and "thread" them through the calls yourself. I think I gave a bad example, the better one would be a function returning datetime in the format of :erlang.localtime: `{{Year,Month,Day},{Hour,Min,Sec}}`. I would like to be able to use this value in a pipeline, by passing only a `{Hour, Min}` tuple to the next call in the pipeline. With pattern_tap it looks like this: :erlang.localtime() |> tap({_, {H,M,_}} ~> {H, M}) |> do_something Without - there are at least 3-4 ways of doing this, each with pros and cons, but all of them are more verbose than pattern_tap. If you want a single value only, there's `elem`, but if you need a few - you're out of luck. `destructure` only works on lists, and `match?` only return a boolean, not whatever was matched. `then` macro makes it a bit better, but you still need to create a lambda with the longhand syntax, which is exactly what I wanted to avoid, so it's hardly a solution, even though it may be the best way to do this for now... EDIT: this is in contrast to Clojure, where maps and vectors are callable, and you get `juxt` in the stdlib. So it's not like pipelines in general can't support convenient extraction of subsets of data flowing through the pipe, it's just that Elixir decided not to support this.
- shakow 5y ago> I think you mean `with`, not `where`? Indeed, my bad. > the better one would be a function returning datetime in the format of :erlang.localtime: `{{Year,Month,Day},{Hour,Min,Sec}}` I see what you mean. Yeah, I agree with the rest.
- losvedir 5y agoHm, this works and is about as terse as `pattern_tap`: :erlang.localtime() |> case do; {_, {h,m,_}} -> {h, m}; end |> do_something Not that I'd want to do that in production code, but I felt a bit nerd-sniped here, to see the shortest way I could find without dependencies.
- klibertp 5y agoThat's actually what pattern_tap's tap macro expands into :) See: https://github.com/mgwidmann/elixir-pattern_tap/blob/master/lib/pattern_tap.ex#L79-L81 https://github.com/mgwidmann/elixir-pattern_tap/blob/master/...
- deleted 5y ago[deleted]