Apologies, I missed that you addressed how `{1, 2, 3} |> pattern_filter({1,
a, b})` would work in your earlier reply, in that you only allow a single
variable to be bound. This further reduces its general applicability.
On Thursday, December 15, 2022 at 4:12:37 PM UTC-5 Ben Wilson wrote:
> Hi Matt,
>
> I am not on the core team nor do I speak for them. From what I have
> generally seen, "alternative APIs" that can be implemented as libraries
> generally should just stay libraries, unless there develops a strong
> following that makes it clear that such an API should be moved into the
> core.
>
> Tangentially, is this code available anywhere?
>
> As for my take on this proposal, I don't really agree with your responses
> to `then`.
>
> > The additional typing involved for the anonymous function distracts the
> reader from the pattern matching, which is the crux of the matter.
>
> 50% of the additional typing is related to specifying the return shape,
> and in this respect that typing is well worth it, because there's no guess
> work. Code is read far more often than written, and the implicit return
> structure of `pattern_filter` leaves me guessing about how it works in
> cases like this:
>
> ```
> {1, 2, 3} |> pattern_filter({1, a, b})
> #=> ?
> ```
>
> `then` is mildly more verbose, but it composes clearly with functions
> without requiring macro magic:
>
> # assertive success
> iex(2)> {1, 2, 3} |> then(fn {1, a, b} -> {a, b} end)
> {2, 3}
>
> # fall back to nil or some other value
> iex(4)> 1 |> then(fn {1, a, b} -> {a, b}; _ -> nil end)
> nil
>
> # assertive failure
> iex(5)> 1 |> then(fn {1, a, b} -> {a, b} end)
> ** (FunctionClauseError)
> ```
>
> `then` doesn't require that you learn any new API, you just do normal
> function stuff and everything works as expected. I'm not seeing a
> significant improvement with `pattern_filter` over this.
>
> - Ben
> On Thursday, December 15, 2022 at 3:48:39 PM UTC-5
> matt.fa...@covermymeds.com wrote:
>
>> Hi again. I’m new to this so apologies if I’m coming off as clueless or
>> pushy. I’m wondering what, if any, next steps there are to advocate for
>> this. Should I share the code? Given what I mentioned in the responses
>> about using one variable or using a new `destructure`, is there still
>> disagreement?
>>
>>
>>
>> Thanks!
>>
>> Matt F
>>
>>
>>
>> *From: * on behalf of Sabiwara Yukichi <
>> sabi...@gmail.com>
>> *Reply-To: *"elixir-l...@googlegroups.com"
>> *Date: *Tuesday, December 13, 2022 at 6:55 PM
>> *To: *"elixir-l...@googlegroups.com"
>> *Subject: *[EXTERNAL] Re: [elixir-core:11213] [proposal] Use patterns to
>> filter data (good for pipes)
>>
>>
>>
>> This email came from a source outside of CoverMyMeds. Use caution when
>> clicking on links or replying with confidential information.
>> --
>>
>> This is an interesting idea, but maybe `then/2` (or case/2 if you're fine
>> piping in it) could already cover these cases quite well (equivalent to
>> your pattern_filter! function):
>>
>>
>>
>> "$3.45" |> then(fn "$" <> money -> money end) |> String.to_float()
>>
>> "$3.45" |> case do "$" <> money -> money end |> String.to_float()
>>
>>
>>
>> The non-raising alternative might be slightly more verbose because you
>> need a second clause. But most of the time (like your money example), the
>> next step of the pipe might fail on nil anyway. Or maybe a with/1 pipeline
>> might work better than the pipe operator if you want a succession of
>> happy-path matches?
>>
>>
>>
>> If we move forward, it might be better to explicitly declare the returned
>> expression, not just infer it from dangling variables: it isn't obvious
>> what should `{a, b}` or `{a, b, a}` return. Something like:
>>
>>
>>
>> {1, 2, 1} |> pattern_filter(b <- {a, b, a})
>>
>>
>>
>> Le mer. 14 déc. 2022 à 05:50, 'Matt Farabaugh' via elixir-lang-core <
>> elixir-l...@googlegroups.com> a écrit :
>>
>> All,
>>
>>
>>
>> I wrote a macro which allows for using a pattern to essentially extract a
>> value from a data structure:
>>
>>
>>
>>
>> @doc """
>> Filter a value out of data using a pattern with one variable. Returns a
>> default value
>> if no match. Raises if pattern contains no variables or more than one
>> variable.
>>
>> ## Examples
>>
>> iex> "$3.45" |> PatternHelpers.pattern_filter("$" <> money) |>
>> String.to_float()
>> 3.45
>>
>> iex> {1,2,3} |> PatternHelpers.pattern_filter({1,_,a})
>> 3
>>
>> iex> %{a: 1, b: 2} |> PatternHelpers.pattern_filter(%{a: 9, b: b})
>> nil
>>
>> iex> %{a: 1, b: 2} |> PatternHelpers.pattern_filter(%{a: 9, b: b}, "???")
>> "???"
>> """
>>
>>
>>
>> And an unsafe version:
>>
>>
>>
>> @doc """
>> See `pattern_filter/3`. Raises if no match.
>>
>> ## Examples
>>
>> iex> {1,2,3} |> PatternHelpers.pattern_filter!({9,_,b})
>> ** (MatchError) no match of right hand side value: {1, 2, 3}
>> """
>>
>>
>>
>> This is my first proposal. Please let me know if this idea is worth some