A small idea

It might be interesting to look at this as an extension of existing 
Kernel.destructure/2: 
https://hexdocs.pm/elixir/1.12/Kernel.html#destructure/2

Right now it works like this

destructure([x, y, z], [1, 2, 3, 4, 5]) # in other words, 
destructure(form_with_bindings, data)

But if we provide another function, say destructure(data, form, new_form, 
default \\ nil), with `new_form` specifying which data it should return 
based on binds from `form`, we can easily use it in pipes like this:

data
|> ...
|> destructure({:ok, result}, result)
|> ...
|> destructure([a, b, c], %{a => 42 + b * c})
|> ...
On Wednesday, 14 December 2022 at 2:36:48 am UTC+1 
matt.fa...@covermymeds.com wrote:

> Thank you for the useful feedback! Let me try addressing your excellent 
> points in turn:
>
>  
>
>    1. While `then/2` and `case/2` are somewhat suitable, they are 
>    verbose, especially in the case of the non-raising alternative. The 
>    additional typing involved for the anonymous function distracts the reader 
>    from the pattern matching, which is the crux of the matter.
>    2. With my implementation, the macro returns an empty string: assert 
>    “” == “$” |> pattern_filter(“$” <> money)
>    3. The `with/1` pipeline is verbose and lacks the visual flow of |>
>    4. The way I wrote the macro stipulates that there is only one 
>    non-underscored variable per pattern. Changing the examples you provided 
> to 
>    `{a, _*b}` and `{*_a, b, _a}` would work just as well and remove 
>    ambiguity as to the return
>       1. So {1,2,1} |> pattern_filter({_a, b, _a}) is more concise and 
>       just as clear, imo
>       2. This does raise a warning, though I’m not sure why the warning 
>       is issued for a pattern like this. It just kind of (politely) tells me 
> to 
>       remove the underscores, though the code works as intended.
>    
>  
>
>  
>
>  
>
>  
>
>  
>
> *From: *<elixir-l...@googlegroups.com> on behalf of Sabiwara Yukichi <
> sabi...@gmail.com>
> *Reply-To: *"elixir-l...@googlegroups.com" <elixir-l...@googlegroups.com>
> *Date: *Tuesday, December 13, 2022 at 6:55 PM
> *To: *"elixir-l...@googlegroups.com" <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 
> attention, and how I might better do my part to present it. I have code 
> obviously but I'm not sure this is the place for it.
>
>  
>
> Thanks,
>
> Matt F
>
> -- 
> You received this message because you are subscribed to the Google Groups 
> "elixir-lang-core" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to elixir-lang-co...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/elixir-lang-core/4b65083e-6c36-4519-a0ed-fa2da8b61a9bn%40googlegroups.com
>  
> <https://urldefense.com/v3/__https:/groups.google.com/d/msgid/elixir-lang-core/4b65083e-6c36-4519-a0ed-fa2da8b61a9bn*40googlegroups.com?utm_medium=email&utm_source=footer__;JQ!!LBRzLL-rxcoG!soAu7_j204hUseqlxMsemQMOhOz0yO8WygSZdV2t7WGq5iDQfDh-prkOc8PkTmo4vz08vKeE_ZmAZ19k2vMrPomauA$>
> .
>
> -- 
> You received this message because you are subscribed to the Google Groups 
> "elixir-lang-core" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to elixir-lang-co...@googlegroups.com.
>
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/elixir-lang-core/CANnyohYy8hRvu2WD%2BMUEzWS2SxoA8eYk9PETOe8jGxr2tiuW%2BA%40mail.gmail.com
>  
> <https://urldefense.com/v3/__https:/groups.google.com/d/msgid/elixir-lang-core/CANnyohYy8hRvu2WD*2BMUEzWS2SxoA8eYk9PETOe8jGxr2tiuW*2BA*40mail.gmail.com?utm_medium=email&utm_source=footer__;JSUl!!LBRzLL-rxcoG!soAu7_j204hUseqlxMsemQMOhOz0yO8WygSZdV2t7WGq5iDQfDh-prkOc8PkTmo4vz08vKeE_ZmAZ19k2vMQT4CMDA$>
> .
>
> This electronic transmission is confidential and intended solely for the 
> addressee(s). If you are not an intended addressee, do not disclose, copy 
> or take any other action in reliance on this transmission. If you have 
> received this transmission in error, please delete it from your system and 
> notify CoverMyMeds LLC at pri...@covermymeds.com. Thank you.
>

-- 
You received this message because you are subscribed to the Google Groups 
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elixir-lang-core+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/4cdeeb01-0446-4385-bea5-062476cc76c2n%40googlegroups.com.

Reply via email to