[elixir-core:11874] Re: Short form of lambdas for zero arguments and unused arguments proposal

2024-08-22 Thread Ben Wilson
Hey Ivan,

You're just missing the introductory &

iex(1)> & &1 + 1
#Function<42.105768164/1 in :erl_eval.expr/6>

On Wednesday, August 21, 2024 at 2:03:24 AM UTC-4 ivan.y...@gmail.com wrote:

> I realize it might be controversial, but I truly enjoy short form lambdas 
> in any language I touch and Elixir is one of them. Yet I think there's a 
> couple of use cases that are uncovered. One is when you need to encode a 
> zero argument lambda returning a value and the second one is when there are 
> more arguments than actually used:
>
> iex(1)> &(&2 + 1)
>
> error: capture argument &2 cannot be defined without &1 (you cannot skip 
> arguments, all arguments must be numbered)
>
> └─ iex:1
>
>
> ** (CompileError) cannot compile code (errors have been logged)
>
>
> iex(1)> &(1)
>
> error: capture argument &1 must be used within the capture operator &
>
> └─ iex:1
>
>
> ** (CompileError) cannot compile code (errors have been logged)
>
> I think both of these cases would be handled if we let explicitly defining 
> the arity of lambda: &2(&2 + 1) or something like that. Since nested 
> lambdas are not allowed anyways, this should work (unless I'm missing 
> something). And we'd assume if there's no access to the variables, it would 
> be a zero argument function, so &(1) would work too.
>
> This should be fundamentally possible, since I can do this:
>
> iex(9)> fn () -> :ok end
>
> #Function<43.105768164/0 in :erl_eval.expr/6>
>
> iex(10)> fn (_a, b) -> b * 2 end
>
> #Function<41.105768164/2 in :erl_eval.expr/6>
>
> So I assume it boils down to parsing? Either way, I'd love to see that in 
> Elixir and I'm willing to contribute some time to get it implemented if the 
> community approves it.
>

-- 
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/11ca2681-4b0e-4875-ac48-455a5e684f6en%40googlegroups.com.


[elixir-core:11801] Re: Collections in Elixir

2024-06-14 Thread Ben Wilson
Hi Miguel,

At the risk of being a bit blunt, this isn't a proposal, nor does it 
reflect familiarity with existing data structures available in the Elixir 
language.

I would perhaps suggest popping over to https://elixirforum.com/ and asking 
some questions about the structures you have asked about, and what versions 
of those exist in the language today.

- Ben

On Wednesday, June 12, 2024 at 3:20:57 PM UTC-4 miguelol...@gmail.com wrote:

> That sounds interesting when I look at other languages that too include 
> that
> On Wednesday, June 12, 2024 at 4:15:23 PM UTC-3 Miguel Oliveira wrote:
>
>> The proposal suggests adding a collections module to the std library. 
>> This module will provide standard data structures (e.g., LinkedList, 
>> HashMap, BTreeMap)
>>
>

-- 
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/8b719dba-5a4c-4b14-847b-37c52a71f4can%40googlegroups.com.


Re: [elixir-core:11542] Support using brackets to access an index of a list

2023-09-22 Thread Ben Wilson
> Personally, I don't see the harm in supporting it.  If someone's going to 
abuse it, they'll abuse Enum.at()

The harm isn't for people who doing it intentionally, the harm is for 
people who are doing it unintentionally. Index based array access is so 
common in certain languages that it's one of the first thing newbies from 
those languages will try in Elixir and if it works then they'll just 
proceed writing loops like:

for i <- 0..length(users) do
  IO.puts users[i].name
end

In doing so they'll have reinforced a non idiomatic pattern, and failed to 
learn something crucial about the language. Of course they can always hit 
the docs and find Enum.at and rewrite it, but if you google: "Elixir access 
list by index" you get stack overflow and forum posts that help you realize 
that you probably don't want to do that. If [] just works they won't google 
till much later.

- Ben

On Friday, September 22, 2023 at 4:28:47 AM UTC-4 ...Paul wrote:

> On Thu, Sep 21, 2023 at 7:19 PM 'Justin Wood' via elixir-lang-core <
> elixir-l...@googlegroups.com> wrote:
>
>> Languages that support it via square brackets: Rust, Ruby, Javascript, 
>> Python, C, Julia.
>>
>> All of these languages (other than maybe Julia? I have not used it at 
>> all.) are actually using arrays and not lists. It is fairly natural to have 
>> easy index based lookup for arrays. After all, it is meant to be a 
>> contiguous block of memory with each element having a known size. At least 
>> for Rust and C, other languages may be more loose in terms of 
>> implementation.
>>
>
> That's the problem.  Ruby, Python, Javascript are where a lot of Elixir 
> devs are coming from (or languages that Elixir devs are often "context 
> switching" with on a daily basis) and these all implement lists that are 
> not actually arrays in the conventional sense.  I'm pretty sure, in all 
> three cases, that a list is actually an object that maintains the list 
> elements -- that might be an actual array of pointers, or it might not.  
> It's definitely not a low-level single allocated block of memory, because 
> these are weakly typed languages an all three support mixed type values (an 
> array in C requires every entry be a fixed size; indexed access is simply 
> multiplying the index by the size of each element and using that as an 
> offset to the start of the memory block -- one of the reasons you can 
> easily segfault by doing that).
>
> Lists in Elixir are linked lists, but we don't regularly refer to them 
> that way.  We don't explicitly reinforce this implementation by requiring 
> things like "LinkedList.new(1, 2, foo)"; we use a "conventional array 
> notation" like "mylist = [1, 2, foo]" -- just like you'd see in Python, 
> Javascript, Ruby.  So it's really not that much of a surprise, coming from 
> those languages, that you start off with that kind of a syntax, and you 
> then expect the language to implement square-bracket-indexing, just like 
> those languages do.  We have Enum.at() to do this, so it's not like it's an 
> impossibility to actually make this work.  The question then is why the 
> syntax doesn't just wrap that function and 'make it work'.  I'm not sure I 
> buy Jose's argument about preventing "non-idiomatic code".  If someone is 
> going to forget that Enum.map exists, they're going to write that loop, and 
> they'll just use Enum.at if they can't get the square brackets to work.
>
> This difference from how those languages have wrapped array-like functions 
> into their syntax has popped up recently with my team, we've noticed people 
> forgetting that the length of a List in Elixir isn't "free information" 
> like it is in Ruby (where the length of a list is actually an attribute of 
> the object representing the list), so we've had to remind people not to do 
> things like "assert length(foo) > 0" (fortunately, a lot of this 
> inefficiency has been limited to our unit tests!) -- because they're coming 
> from Ruby where the length of a list is always "known", so it doesn't even 
> occur to them (and I admit, I've been guilty of forgetting this 
> occasionally as well) that Enum.count() and length() both actively loop 
> over an argument to compute the length, and aren't just retrieving some 
> privately cached data.
>
> As an aside, the one oddity around Access' square-bracket-index 
> implementation that still throws me every once in a while is why you can't 
> use square brackets to index a field on a struct.  If you have a Map, you 
> can do foo[key] but on a struct, foo[key] throws an exception.  Where it 
> gets annoying is that the way to make this work on a struct is to actually 
> use Map.get -- a Map function!  If a struct is a Map, why can't Access just 
> treat structs like Maps in this situation?  But that's a completely 
> different discussion, and I digress.  ;)
>
> Personally, I don't see the harm in supporting it.  If someone's going to 
> abuse it, they'll abuse Enum.at() to make it work anyway, just like 

[elixir-core:11426] Re: [Proposal] Syntax sugar for Maps construction and pattern matching

2023-06-26 Thread Ben Wilson
Hi,

This has been proposed before. Someone came up 
with https://github.com/meyercm/shorter_maps which accomplishes this as a 
macro. It might be worth a discussion again at this point but it is worth 
noting that this is a proposal that has been on this list before, and so it 
would likely be good to address considerations raised there in this new 
proposal.

- Ben

On Monday, June 26, 2023 at 3:36:16 PM UTC-4 torres@gmail.com wrote:

> Hi,
> I'd like to propose a syntax sugar for maps, specially for pattern 
> matching and construction.
>
> # Map construction
> language = :elixir
> %{ language }
> => %{language: :elixir}
>
>
> # Map pattern match
> map = %{feature: :pattern_match}
> %{ feature } = map
> => %{feature: :pattern_match}
> feature
> => :pattern_match
>
> case %{ key: "some value" } do
> %{key} ->
>   key
>   _ ->
>   nil
> end
> => "some value"
>
>
> # Map in function args
> defmodule Foo do
> def bar(%{ key }),
>   do: key
> end
>
> Foo.bar(%{ key: "some value" })
> => "some value"
>
>
> Of course this would be just a syntax sugar. It won't compromise program's 
> performance.
>
> The advantage of that is mainly when pattern matching function, but also 
> *case* and *with* statements, on maps with some considerable amount of 
> keys.
>
>
> with %{ key1 } <- %{key1: "value1"},
> {:ok, %{key2, key3, key4, key5}} <-
>   {:ok, %{key2: "value2", key3: "value3", key4: "value4", key5: "value5"}} 
> do
> {key1, key2, key3, key4, key5}
> end
> => {"value1", "value2", "value3", "value4", "value5"}
>
>
> I'd like to know if more people would be interested on that too.
>

-- 
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/56ed3f2e-c696-4986-9e34-b31b720d49a9n%40googlegroups.com.


Re: [elixir-core:11420] Re: [Proposal] Pretty print diff when matching on context fails in ExUnit

2023-05-28 Thread Ben Wilson
That would be lovely as well. My main question there is if there are 
performance concerns invoking the formatter in such cases? I can't imagine 
it'd be an issue for test failures, but general pattern match exceptions 
seem like they might be more sensitive to such things.

And possibly a relevant question in both cases: How well does this work 
with inspect limits that end up eliding parts of the data?

On Sunday, May 28, 2023 at 12:35:40 PM UTC-4 José Valim wrote:

> If we are going down this path, then my suggestion would be to add this to 
> all of Elixir itself, starting with function clause errors. :) If someone 
> wants to explore this path, please go ahead!
>
> On Sun, May 28, 2023 at 5:13 PM Ben Wilson  wrote:
>
>> Agreed. Can the formatter get invoked on output like that I wonder?
>>
>> On Friday, May 26, 2023 at 3:32:02 AM UTC-4 ifu...@gmail.com wrote:
>>
>>> Consider the following code:
>>>
>>> setup do
>>> %{a: 1}
>>> end
>>>
>>> test "test", %{b: b} do
>>> IO.inspect(b)
>>> end
>>>
>>> if we run the test, then it fails with the following error:
>>>   1) test test (SandboxTest)
>>>  test/sandbox_test.exs:8
>>>  ** (FunctionClauseError) no function clause matching in 
>>> SandboxTest."test test"/1
>>>
>>>  The following arguments were given to SandboxTest."test test"/1:
>>>  
>>>  # 1
>>>  %{a: 1, async: false, case: SandboxTest, describe: nil, 
>>> describe_line: nil, file: 
>>> "/home/artur/projects/sandbox/test/sandbox_test.exs", line: 8, module: 
>>> SandboxTest, registered: %{}, test: :"test test", test_type: :test}
>>>  
>>>  code: test "test", %{b: b} do
>>>  stacktrace:
>>>test/sandbox_test.exs:8: (test)
>>>
>>>
>>> A way better error reporting is present if the test uses assert macro:
>>>
>>> setup do
>>> %{a: 1}
>>> end
>>>
>>> test "test", context do
>>> assert %{b: b} = context
>>> IO.inspect(b)
>>> end
>>>
>>> Error:
>>>   1) test test (SandboxTest)
>>>  test/sandbox_test.exs:9
>>>  match (=) failed
>>>  code:  assert %{b: b} = context
>>>  left:  %{b: b}
>>>  right: %{
>>>   a: 1,
>>>   async: false,
>>>   case: SandboxTest,
>>>   describe: nil,
>>>   describe_line: nil,
>>>   file: "/home/artur/projects/sandbox/test/sandbox_test.exs",
>>>   line: 9,
>>>   module: SandboxTest,
>>>   registered: %{},
>>>   test: :"test test",
>>>   test_type: :test
>>> }
>>>  stacktrace:
>>>test/sandbox_test.exs:10: (test)
>>>
>>> It would be great if something similar is reported for the first code 
>>> snippet.
>>>
>> -- 
>> 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/513c8678-e03c-40da-9163-9cfd7e9c943bn%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/elixir-lang-core/513c8678-e03c-40da-9163-9cfd7e9c943bn%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>

-- 
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/5f8ef0b6-0b6f-41d7-90df-73a24c3226f2n%40googlegroups.com.


[elixir-core:11417] Re: [Proposal] Pretty print diff when matching on context fails in ExUnit

2023-05-28 Thread Ben Wilson
Agreed. Can the formatter get invoked on output like that I wonder?

On Friday, May 26, 2023 at 3:32:02 AM UTC-4 ifu...@gmail.com wrote:

> Consider the following code:
>
> setup do
> %{a: 1}
> end
>
> test "test", %{b: b} do
> IO.inspect(b)
> end
>
> if we run the test, then it fails with the following error:
>   1) test test (SandboxTest)
>  test/sandbox_test.exs:8
>  ** (FunctionClauseError) no function clause matching in 
> SandboxTest."test test"/1
>
>  The following arguments were given to SandboxTest."test test"/1:
>  
>  # 1
>  %{a: 1, async: false, case: SandboxTest, describe: nil, 
> describe_line: nil, file: 
> "/home/artur/projects/sandbox/test/sandbox_test.exs", line: 8, module: 
> SandboxTest, registered: %{}, test: :"test test", test_type: :test}
>  
>  code: test "test", %{b: b} do
>  stacktrace:
>test/sandbox_test.exs:8: (test)
>
>
> A way better error reporting is present if the test uses assert macro:
>
> setup do
> %{a: 1}
> end
>
> test "test", context do
> assert %{b: b} = context
> IO.inspect(b)
> end
>
> Error:
>   1) test test (SandboxTest)
>  test/sandbox_test.exs:9
>  match (=) failed
>  code:  assert %{b: b} = context
>  left:  %{b: b}
>  right: %{
>   a: 1,
>   async: false,
>   case: SandboxTest,
>   describe: nil,
>   describe_line: nil,
>   file: "/home/artur/projects/sandbox/test/sandbox_test.exs",
>   line: 9,
>   module: SandboxTest,
>   registered: %{},
>   test: :"test test",
>   test_type: :test
> }
>  stacktrace:
>test/sandbox_test.exs:10: (test)
>
> It would be great if something similar is reported for the first code 
> snippet.
>

-- 
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/513c8678-e03c-40da-9163-9cfd7e9c943bn%40googlegroups.com.


Re: [elixir-core:11396] Proposal: Add ~URI sigil

2023-05-18 Thread Ben Wilson
Question: Would this sigil support interpolation? Is that too clever?

~URI"https://#{path}?#{query_params}";

- Ben

On Thursday, May 18, 2023 at 1:37:37 AM UTC-4 christ...@gmail.com wrote:

> I dislike +1 posts, but I feel very strongly about this—it'd be amazing to 
> have.
>
> I want booting an application to fail as fast and obviously as possible if 
> someone gives it a bad phoenix host url, ecto database url, rabbitMQ url, 
> redis url, mongodb url, etc. Preferably, before the connection is 
> attempted; which, depending on the library in question consuming the url, 
> often fails with a confusing network-failure-related error message.
> On Tuesday, May 16, 2023 at 7:51:21 PM UTC-4 Kip wrote:
>
>> I think this is a good proposal, as is the ~UTC one.  Both make the 
>> intent much clearer.
>>
>> On 16 May 2023, at 6:45 pm, Wojtek Mach  wrote:
>>
>> I just realised another small benefit of showing the full URL in the 
>> sigil. Here’s a snippet from the proposal as rendered by my e-mail client:
>>
>> 
>>
>>
>> The URL was automatically made clickable. Tools like Livebook could 
>> potentially do the same.
>>
>> On 16 May 2023, at 10:38, Wojtek Mach  wrote:
>>
>> Hi, I'd like to propose adding ~URI for constructing URI structs. Here's 
>> an example:
>>
>> iex> ~URI"https://elixir-lang.org";
>> %URI{
>>   scheme: "https",
>>   authority: "elixir-lang.org",
>>   userinfo: nil,
>>   host: "elixir-lang.org",
>>   port: 443,
>>   path: nil,
>>   query: nil,
>>   fragment: nil
>> }
>>
>> I believe the advantage is we can make this a macro and thus parse the 
>> URI string at compile-time
>> so catch bugs because of incorrect format early (though these are pretty 
>> uncommon) and also be a
>> little bit more efficient at runtime.
>>
>> If added, I'm not sure whether ~URI should use URI.parse or URI.new! 
>> under the hood so an advice
>> on that would be appreciated.
>>
>> This is a separate but related discussion so while at it, I'd like to 
>> propose adding Inspect
>> implementation for URI that would return the sigil:
>>
>> iex> ~URI"https://elixir-lang.org";
>> ~URI"https://elixir-lang.org";
>>
>> I think more compact representation helps e.g. here. Before:
>>
>> iex> Req.new(url: "https://elixir-lang.org";)
>> %Req.Request{
>>   method: :get,
>>   url: %URI{
>> scheme: "https",
>> authority: "elixir-lang.org",
>> userinfo: nil,
>> host: "elixir-lang.org",
>> port: 443,
>> path: nil,
>> query: nil,
>> fragment: nil
>>   },
>>   headers: [],
>>   body: nil,
>>   options: %{},
>>   ...
>> }
>>
>> After:
>>
>> iex> Req.new(url: "https://elixir-lang.org";)
>> %Req.Request{
>>   method: :get,
>>   url: ~URI"https://elixir-lang.org";,
>>   headers: [],
>>   body: nil,
>>   options: %{},
>>   ...
>> }
>>
>> On the other hand, seeing the internal representation right away is 
>> sometimes useful given the URI
>> format is somewhat subtle.
>>
>> Before:
>>
>> iex> URI.parse("/foo")
>> %URI{
>>   scheme: nil,
>>   userinfo: nil,
>>   host: nil,
>>   port: nil,
>>   path: "/foo",
>>   query: nil,
>>   fragment: nil
>> }
>> iex> URI.parse("//foo")
>> %URI{
>>   scheme: nil,
>>   authority: "foo",
>>   userinfo: nil,
>>   host: "foo",
>>   port: nil,
>>   path: nil,
>>   query: nil,
>>   fragment: nil
>> }
>>
>> After:
>>
>> iex> URI.parse("/foo")
>> ~URI"/foo"
>> iex> URI.parse("//foo")
>> ~URI"//foo"
>>
>> I think this downside can be alleviated by adding `IEx.Info` 
>> implementation along these lines:
>>
>> iex> i URI.parse("/foo")
>> Term
>>   ~URI"/foo"
>> Data type
>>   URI
>> Raw representation
>>   %URI{
>> scheme: nil,
>> userinfo: nil,
>> host: nil,
>> port: nil,
>> path: "/foo",
>> query: nil,
>> fragment: nil
>>   }
>>
>> -- 
>> 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/9cc29c5e-ca64-42b3-83f8-84c60985efedn%40googlegroups.com
>>  
>> 
>> .
>>
>>
>>
>> -- 
>> 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/5D183EE3-56B8-41BB-8D23

Re: [elixir-core:11303] Multi-letter (uppercase) sigils

2023-03-05 Thread Ben Wilson
I'm generally +1 on this, but I am a tiny bit confused about the proposed 
change to interpolation. Does this propose a change to interpolation for 
all sigils, single or multi letter? If so, what is the deprecation plan for 
the current interpolation syntaxx?

On Sunday, March 5, 2023 at 2:21:47 PM UTC-5 José Valim wrote:

> This has been accepted and merged. Thanks everyone.
>
> On Sun, Mar 5, 2023 at 4:12 PM Bruce Tate  wrote:
>
>> This change would be a most welcome one. Sigils are going to be more 
>> important as Elixir expands into new domains, and it's helpful to have 
>> clues to what each sigil does. 
>>
>> The restrictions to upper case seem to be reasonable ones. 
>>
>> -bt
>>
>> On Sat, Mar 4, 2023 at 3:15 AM José Valim  wrote:
>>
>>> Sigils in Elixir are currently limited to a single letter. We had many 
>>> discussions in the past about allowing more letters but they were 
>>> ultimately rejected because of lowercase sigils.
>>>
>>> The issue with multi-letter lowercase sigils is that:
>>>
>>> 1. they are ambiguous to humans
>>> 2. they are ambiguous to machines
>>> 3. they may have security implications
>>>
>>> For instance, I would say that sigils in Elixir have quite distinctive 
>>> features:
>>>
>>> var = ~w"foo"
>>> var = ~w[bar]
>>>
>>> Tilde, a letter, and the content surrounded by terminators. However, 
>>> given how most identifiers in the language are lowercase, I think using a 
>>> multi-letter starts to become less clear. For example, imagine we supported 
>>> a sigil named opts:
>>>
>>> var = ~opts[bar]
>>>
>>> That's awfully close to:
>>>
>>> var =~ opts[bar]
>>>
>>> Which would in fact be ambiguous at the parser level.
>>>
>>> The other aspect is that security recommendations suggest different 
>>> interpolations to be used for different aspects. For example, imagine 
>>> someone wants to implement a SQL query sigil that automatically escapes 
>>> characters. Today, one could write this:
>>>
>>> ~q"""
>>> SELECT * FROM posts WHERE id = #{id}
>>> """
>>>
>>> And that would be safe! But the fact we are using interpolation means 
>>> someone can simply forget the ~q at the front and write an _unsafe_ query. 
>>> It would be much better if the interpolation is different altogether:
>>>
>>> ~SQL"""
>>> SELECT * FROM posts WHERE id = {{id}}
>>> """
>>>
>>> On one hand, it may feel inconsistent to have different ways to 
>>> interpolate, but at the same time it is reasonable to use different 
>>> mechanisms when different behaviours and security trade-offs are involved. 
>>> Especially because #{...} typically means string conversion and that's not 
>>> the case for SQL queries (it is simply parameter placement).
>>>
>>> With all of this in mind, the suggestion is to allow only multi-letter 
>>> uppercase sigils. Most sigils are uppercase anyway:
>>>
>>> 1. Elixir defines 4 lowercase sigils (~r, ~s, ~w, and ~c) but 8 
>>> uppercase ones (the four previous plus ~T, ~D, ~N, ~U for datetimes)
>>> 2. Nx uses ~V and ~M for vectors and matrices respectively
>>> 3. LiveView uses ~H, Surface uses ~F, and LiveView Native will need at 
>>> least two uppercase sigils for Swift UI and Jetpack Compose
>>>
>>> Therefore, I would like to propose for multi-letter uppercase only 
>>> sigils to be introduced and be, from now on, the recommendation for new 
>>> libraries. This means we won't deprecate ~T, ~D, ~N, ~U in Elixir, but 
>>> there is still time to rewrite ~V and ~M in Nx to ~VEC and ~MAT. LiveView 
>>> and Surface can decide if they want to migrate or not, ~SF may be a better 
>>> choice for the latter, but LiveView Native can choose to support, for 
>>> example, between ~JETPACK or ~JC if it prefers an abbreviation.
>>>
>>> Looking forward to feedback,
>>>
>>>
>>>
>>> -- 
>>> 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/CAGnRm4KTx%2BYW02gQLvH-ihyhgv6dAhjrwSEdhP81niuvjrWfTg%40mail.gmail.com
>>>  
>>> 
>>> .
>>>
>>
>>
>> -- 
>>
>> Regards,
>> Bruce Tate
>> CEO
>>
>>
>> 
>>
>> Groxio, LLC.
>> 512.799.9366 <(512)%20799-9366>
>> br...@grox.io
>> grox.io
>>
>> -- 
>> 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/CAFXvW-6_r_vqo6ccXHT79JQO1RdaLOwdanfSqN7VsxZRWACm_g

Re: [EXTERNAL] Re: [elixir-core:11221] [proposal] Use patterns to filter data (good for pipes)

2022-12-15 Thread Ben Wilson
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 
&

Re: [EXTERNAL] Re: [elixir-core:11219] [proposal] Use patterns to filter data (good for pipes)

2022-12-15 Thread Ben Wilson
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 
> 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/

[elixir-core:11190] Re: Proposal: Introduce string limit function.

2022-11-19 Thread Ben Wilson
This seems reasonably straight forward to implement in your own code base:

```
def truncate(string, length, padding \\ ".") do
  string
  |> String.slice(0, length)
  |> String.pad_trailing(String.length(string), padding)
end
```

Not seeing a strong need to include it in the standard library. Just my 
$0.02
On Saturday, November 19, 2022 at 2:12:19 PM UTC-5 Kip wrote:

> That is comes from Laravel, not PHP core may be an indication it is better 
> implemented in a library?  If there is momentum towards adding it to the 
> String module I think `String.truncate` would feel more natural to me (its 
> also what Ruby uses).  
>
> Its difficult to make guarantees about the printable width though since 
> characters like ZWJ and Bidi text would mean that to do this properly is 
> not a simple or straight forward situation.  For that reason I don't 
> personally think it belongs in Elixir itself.
>
> On Saturday, November 19, 2022 at 5:20:21 PM UTC+1 hassanr...@gmail.com 
> wrote:
>
>> Hi all,
>> I came across from laravel  framework, where there 
>> are a lot of useful functions, I miss those functions in Elixir, One of the 
>> functions is called limit 
>>  function, I 
>> would like to have that in elixir.
>> ```
>> iex> String.limit("elixir", 3)
>> "eli..."
>>
>> iex> String.limit("elixir", 7)
>> "elixir"
>>
>> iex> String.limit("elixir", 3, "***")
>> "eli***"
>> ```
>> This function would be really helpful with longer string, we can limit 
>> long string with some trailing string like (...).
>>
>> What do you think? If yes what should be the name you suggest?
>>
>> Thanks,
>> Hassan
>>
>>
>>
>>

-- 
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/35628c34-c8c4-4558-a985-de87ec7111d3n%40googlegroups.com.


Re: [elixir-core:11166] A More Human DateTime Comparison API

2022-10-31 Thread Ben Wilson
Making < and <= work in general for DateTime has been discussed and isn't 
feasible. The macro answer I kinda love.

On Monday, October 31, 2022 at 3:42:16 PM UTC-4 m...@achempion.com wrote:

> Is it possible to modify language in a way to make >,<, = work for dates?
>
> The datetime's struct has known values 
> 
>  which 
> can be pattern matched against and struct comparison, in general, is not 
> used that match, so it shouldn't mess up with already written code (maybe 
> we even fix couple bugs as using >,<,= to compare dates are relatively 
> common first bug for new elixir developers). 
>
> If we can ducktype struct with such attributes and use a regular 
> DateTime.compate/2 to compare it in Kernel.>/2 function and friends.
>
> On 31 Oct 2022, at 19:54, Cliff  wrote:
>
> I did some more playing around and created this macro:
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> *defmodule Foo do  defmacro compare_with(comparison, module) do{op, 
> _env, [a, b]} = comparisoncmp_result = quote do  
> unquote(module).compare(unquote(a), unquote(b))endcase op do  
> :> ->{:==, [], [cmp_result, :gt]}  :< ->{:==, [], 
> [cmp_result, :lt]}  :>= ->{:!=, [], [cmp_result, :lt]}  :<= 
> ->{:!=, [], [cmp_result, :gt]}end  endend*
>
> I don't think it is actually a good solution to this issue, but just 
> wanted to share the idea.
>
> *(a >= b) |> compare_with(DateTime)*
>
> On Monday, October 31, 2022 at 2:46:09 PM UTC-4 benwil...@gmail.com wrote:
>
> > DateTime.compare(a, :<, b) would get my vote of the alternative 
>> proposals but I think it doesn't move much the needle in comparison to 
>> DateTime.compare.
>>
>> To me this is a pretty big difference difference, because with an 
>> `import` it does 2 things:
>>
>> 1) Eliminates the existence of an irrelevant, boilerplate operator ==
>> 2) positions the 2 values you care about correctly with respect to the 
>> relevant operator
>>
>> When you have
>>
>> DateTime.compare(a, b) == :lt
>>
>> it's like RPN, you have to hold a and b in your head, remember their 
>> order, then skip past the `==` since it doesn't matter, and finally you get 
>> to see your comparison. When discussing this in complex contexts the need 
>> to try to distinguish about whether you're talking about what the _function 
>> call is equal to_ from whether the values themselves are equal to is 
>> actually a pretty big deal. There are basically 4 characters with semantic 
>> value, and there rest are boilerplate. When you have a bunch of these all 
>> next to each other (like when building up complex range helpers) 
>> https://gist.github.com/benwilson512/456735775028c2da5bd38572d25b7813 it's 
>> just a ton of data to filter out.
>>
>> If you could `import DateTime, compare?: 3` this could be
>>
>> compare?(a, :<, b)
>> compare?(a, :<=, b)
>>
>> On Monday, October 31, 2022 at 2:02:03 PM UTC-4 Cliff wrote:
>>
> > in Elixir the subject is always the first argument
>>>
>>> Ah, that clears it up for me, I hadn't yet realized that symmetry in the 
>>> APIs. I like the before?/after? functions now.
>>>
>>> On Monday, October 31, 2022 at 1:16:52 PM UTC-4 José Valim wrote:
>>>
>> I am not worried about the argument order because in Elixir the subject 
 is always the first argument. So it is always "is date1 before date2?". I 
 like the :inclusive option if the need ever arises.

 DateTime.compare(a, :<, b) would get my vote of the alternative 
 proposals but I think it doesn't move much the needle in comparison to 
 DateTime.compare.

 On Mon, Oct 31, 2022 at 5:44 PM Cliff  wrote:

>>> I would prefer the atoms *:before*, and *:after* rather than 
> :gt/:greater_than/etc. Since we're already solving the problem of 
> operator/argument ordering, why not remove the final mental barrier of 
> reasoning about whether a time being "greater than" another time means 
> that 
> it is before or after? *foo(a, :gt, b)* still requires a second 
> thought ("Is a bigger time earlier or later?"), whereas if I read code 
> that 
> said *foo(a, :before, b)* I would feel confident in my understanding 
> after only the first read.
>
> On Monday, October 31, 2022 at 12:35:05 PM UTC-4 lui...@gmail.com 
> wrote:
>
 I also prefer something like *DateTime.compare(a, operator, b)*.
>>
>> Operators don't need to be *cryptic* like *:eq*, *:gt*, *:lte*, 
>> etc., we can use the same comparison operators we already are used to:
>>
>> *DateTime.compare(a, :<, b)*
>> *DateTime.compare(a, :==, b)*
>> *DateTime.compare(a, :>=, b)*
>>
>> It's clear and much less verbose than the Ecto's (which was a great 
>> suggestion, by the way).
>>
>> On Monday, October 31, 2022 at 5:23:54 PM UTC+1 and...@dryga.com 
>> wrote:
>>
> Hey

Re: [elixir-core:11163] A More Human DateTime Comparison API

2022-10-31 Thread Ben Wilson
> DateTime.compare(a, :<, b) would get my vote of the alternative proposals 
but I think it doesn't move much the needle in comparison to 
DateTime.compare.

To me this is a pretty big difference difference, because with an `import` 
it does 2 things:

1) Eliminates the existence of an irrelevant, boilerplate operator ==
2) positions the 2 values you care about correctly with respect to the 
relevant operator

When you have

DateTime.compare(a, b) == :lt

it's like RPN, you have to hold a and b in your head, remember their order, 
then skip past the `==` since it doesn't matter, and finally you get to see 
your comparison. When discussing this in complex contexts the need to try 
to distinguish about whether you're talking about what the _function call 
is equal to_ from whether the values themselves are equal to is actually a 
pretty big deal. There are basically 4 characters with semantic value, and 
there rest are boilerplate. When you have a bunch of these all next to each 
other (like when building up complex range 
helpers) https://gist.github.com/benwilson512/456735775028c2da5bd38572d25b7813 
it's just a ton of data to filter out.

If you could `import DateTime, compare?: 3` this could be

compare?(a, :<, b)
compare?(a, :<=, b)

On Monday, October 31, 2022 at 2:02:03 PM UTC-4 Cliff wrote:

> > in Elixir the subject is always the first argument
>
> Ah, that clears it up for me, I hadn't yet realized that symmetry in the 
> APIs. I like the before?/after? functions now.
>
> On Monday, October 31, 2022 at 1:16:52 PM UTC-4 José Valim wrote:
>
>> I am not worried about the argument order because in Elixir the subject 
>> is always the first argument. So it is always "is date1 before date2?". I 
>> like the :inclusive option if the need ever arises.
>>
>> DateTime.compare(a, :<, b) would get my vote of the alternative proposals 
>> but I think it doesn't move much the needle in comparison to 
>> DateTime.compare.
>>
>> On Mon, Oct 31, 2022 at 5:44 PM Cliff  wrote:
>>
>>> I would prefer the atoms *:before*, and *:after* rather than 
>>> :gt/:greater_than/etc. Since we're already solving the problem of 
>>> operator/argument ordering, why not remove the final mental barrier of 
>>> reasoning about whether a time being "greater than" another time means that 
>>> it is before or after? *foo(a, :gt, b)* still requires a second thought 
>>> ("Is a bigger time earlier or later?"), whereas if I read code that said 
>>> *foo(a, 
>>> :before, b)* I would feel confident in my understanding after only the 
>>> first read.
>>>
>>> On Monday, October 31, 2022 at 12:35:05 PM UTC-4 lui...@gmail.com wrote:
>>>
 I also prefer something like *DateTime.compare(a, operator, b)*.

 Operators don't need to be *cryptic* like *:eq*, *:gt*, *:lte*, etc., 
 we can use the same comparison operators we already are used to:

 *DateTime.compare(a, :<, b)*
 *DateTime.compare(a, :==, b)*
 *DateTime.compare(a, :>=, b)*

 It's clear and much less verbose than the Ecto's (which was a great 
 suggestion, by the way).

 On Monday, October 31, 2022 at 5:23:54 PM UTC+1 and...@dryga.com wrote:

> Hey guys, as an idea why don't we reuse atoms from Ecto: 
>
>- :less_than
>- :greater_than
>- :less_than_or_equal_to
>- :greater_than_or_equal_to
>- :equal_to
>- :not_equal_to
>
> I feel like they are fairly common nowadays and even though it's more 
> to type make it easier to understand when you want an inclusive 
> comparison. 
>
> We can later make it part of all modules that have `compare/2` (Date, 
> DateTime, Time, Version, etc).
>
> On Monday, October 31, 2022 at 10:10:09 AM UTC-6 Cliff wrote:
>
>> I prefer the form *DateTime.is(a, operator, b)*, but I agree with 
>> others that it would need a more sensible name than "is". 
>>
>> Regarding the form *DateTime.before?(a, b)*, I could still see 
>> myself getting confused by argument order. *before?(a, b)* might be 
>> read as "before A happened, B happened", rather than the intended "A 
>> happened before B". the *is(a, :before, b)* form, however, is read 
>> exactly how it would be spoken.
>>
>> Regarding comparison inclusivity, another possibility is a keyword 
>> option: *DateTime.before?(a, b, inclusive: true)*
>>
>> On Monday, October 31, 2022 at 3:45:15 AM UTC-4 simonmc...@gmail.com 
>> wrote:
>>
>>> DateTime.before?(a, b) is much nicer than DateTime.compare(a, b) == 
>>> :lt.  It doesn't completely remove the argument order issue but I 
>>> reckon it 
>>> would resolve it for me.  I run DateTime.compare(a, b) in iex every 
>>> time I 
>>> use the function because I'm terribly forgetful and paranoid.  I would 
>>> prefer DateTime.eq?/lt?/le?/gt?/ge? instead of 
>>> before?/after?/on_or_before?/on_or_after? which is shorter, matches 
>>> compare/2 

Re: [elixir-core:11107] Partially applied pipelines/currying/etc

2022-10-25 Thread Ben Wilson
I think it would be helpful to see examples of regular Elixir code today 
that would be improved with this operator. The Plug example doesn't really 
work for me because Plug is doing a bunch of compile time stuff anyway and 
it also isn't using the pipe operator.

On Tuesday, October 25, 2022 at 10:56:14 PM UTC-4 dorga...@gmail.com wrote:

> For the plugs example, how is it better than the alternative that exists 
> today?
>
> browser_pipeline =
>   fn conn -> conn |> accepts("html") |> fetch_session() |> fetch_flash() 
> |> protect_from_forgery() end
>
> This would allow pipelines to be composed. Think Plug, but functional.
>>
> I think this is a preculiarity of how the plug/phoenix DSL works and not 
> an issue with Elixir itself. Assuming there is a problem with the way 
> pipelines are defined, wouldn't that call for a different design at the 
> library level instead of a change in Elixir itself?
>
> Function composition is a key part of FP.
>>
> Agreed, but functional composition(h = g ∘ f) is not the way the 
> overwhelming majority of elixir code is written, as it's more "idiomatic" 
> to write programs that operate on a data structure and not by composing 
> functions together. We say that two functions compose when the input of one 
> matches the input of the other and we fully leverage that to write 
> pipelines, but we don't write programs by defining more functions via 
> functional composition.
>
> El mar, 25 oct 2022 a las 21:46, pragdave () escribió:
>
>> I know this has been discussed before, in different forms, but I thought 
>> I’d just have another go following my recent earth-shattering PR :)
>>
>> I’d like to propose a new unary operator, &>. It works just like the 
>> pipeline |>, but doesn’t take a left argument. Instead it returns an 
>> arity 1 function that, when called, executes the pipeline.
>>
>> toCamel = &> downcase |> split("_") |> map(&capitalize/1) |> join
>>
>> toCamel.("now is")   # => "NowIs""the_time" |> toCamel.() # => 
>> "the time"
>>
>> Why? 
>>
>>- 
>>
>>Function composition is a key part of FP. It would be nice to support 
>>it natively.
>>- 
>>
>>The current pipeline semantic both defines a processing flow *and 
>>executes it*. Splitting this into two would allow a lot more 
>>expressiveness.
>>- 
>>
>>This would allow pipelines to be composed. Think Plug, but functional 
>>.
>>
>>   pipeline :browser do 
>>
>>   plug :accepts, ["html"] 
>>
>>   plug :fetch_session 
>>
>>   plug :fetch_flash 
>>
>>   plug :protect_from_forgeryend
>>
>> would become
>>
>> browser_pipeline =
>>   &> accepts("html") |> fetch_session |> fetch_flash |> protect_from_forgery
>>
>> The cool thing here is that each of the elements of the pipe is simply a 
>> function, and could be a nested pipeline. For example, we could create an 
>> authenticated pipeline by embedding the browser pipeline:
>>
>> authenticated_pipeline = &> browser_pipeline.() |> authenticate
>>
>> How? 
>>
>> If we created a new prefix operator in the interpreter, then we could 
>> implement a proof of concept as a library. Folks could then use this for a 
>> while to see if the idea has merit, and if so, possibly roll this into the 
>> language syntax.
>>
>> I’d be happy to do this if there’s interest.
>>
>> Dave
>> ​
>>
>> -- 
>> 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/a5b1186c-a4ea-4f50-8143-354738f47632n%40googlegroups.com
>>  
>> 
>> .
>>
>

-- 
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/b65549eb-89fb-47f6-b6ce-eb226ab75538n%40googlegroups.com.


[elixir-core:11036] Re: Flow Ecto like assertions in ExUnit

2022-09-05 Thread Ben Wilson
Seems like a good opportunity for a library. There's not anything I'm 
seeing there that would require changes to the core language. Building a 
library is a good way to test out if it's a popular idea and work though 
any of the design challenges.

On Sunday, September 4, 2022 at 3:52:04 PM UTC-4 pcarv...@gmail.com wrote:

> It would be nice if you could assert fields of structures in a piped ecto 
> like style.
>
> Ex:
> my_struct
> |> assert_not_nil([:some_field,:other_field]
> |> assert_exists([:another_field])
> |> do_something()
> |> assert_expression([new_struct],  new_struct.another_field != 
> my_struct.another_field  )
>

-- 
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/53ac7704-2444-4308-8e77-3e3f1b4d216en%40googlegroups.com.


[elixir-core:11017] Re: Proposal: Warn on assert %{} = x

2022-08-16 Thread Ben Wilson
To me this feels like a good use of credo or similar linter, not something 
that the Elixir compiler itself should warn about. `assert %{} = x` isn't 
the most idiomatic way to match but it isn't incoherent or invalid, just 
probably not best practice.

On Tuesday, August 16, 2022 at 5:55:09 AM UTC-4 woj...@wojtekmach.pl wrote:

> Hi,
>
> Developers can easily shoot themselves in the foot if they write:
>
> assert %{} = x
>
> but really what they meant was to write:
>
> assert %{} == x
>
> The mistake is writing `=` instead of `==`, an easy one to make. The 
> difference is of course that the former will succeed on _any_ map and the 
> latter will _only_ succeed on an _empty_ map.
>
> I'd like to propose ExUnit warn on `assert %{} = x` and tell users to 
> instead write `assert is_map(x)`.
>
> Thoughts?
>
> P.S. In my projects I'd either write `assert actual == expected` OR 
> `assert expected = actual` and never `assert expected == actual` exactly 
> because it is easy to make the mistake. Maybe there is a Credo check to 
> enforce such style.
>

-- 
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/b70a4bb4-14d4-4ea3-8b49-45b408abf750n%40googlegroups.com.


Re: [elixir-core:10959] `Map.get/3` to return default value for `nil` value

2022-06-23 Thread Ben Wilson
> `Map.get(map, key, default_value)` looks better than `Map.get(map, key) 
|| default_value`

This isn't a matter of looks, these have straight up different 
functionality. You can't change this sort of thing in the language at this 
point in its lifecycle. Plus, you'd be forcing everyone who's doing that 
first thing to change to the far uglier multiline:

```
case Map.fetch(map, key) do
  {:ok, value} -> value
  _ -> default_value
end
```
On Wednesday, June 22, 2022 at 8:22:50 AM UTC-4 halos...@gmail.com wrote:

>
> On Jun 22, 2022, at 04:37, Nganga Mburu  wrote:
>
> 
>
> We've used `map[key] || default_value`, or even `Map.get(map, key) || 
> default_value` before but I felt this being handled my `Map.get/3` would 
> be better.
>
> `Map.get(map, key, default_value)` looks better than `Map.get(map, key) 
> || default_value`
>
>
> This assumes that `nil` isn’t a valid value. For your use-case it may be. 
> For other cases, it may be a valid and important value.
>
> I know for a fact that this would break some production code we run and be 
> a surprising result for us because it would not behave the way we expect 
> for anything else, including JavaScript Map.get.
>
> -a
>

-- 
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/7aa588ab-5aea-4138-8e93-82bed15841ban%40googlegroups.com.


[elixir-core:10879] Re: [Proposal] GenServer response with exception control flow

2022-04-26 Thread Ben Wilson
> I'm sure there is the opinion that this is anti-pattern

Yup. Side stepping this a bit though and getting to something deeper: This 
does not seem like it needs to be part of the standard library. You could 
make a library called GenServerWithExceptions or something and put it up on 
hex, and see if people use it. If it's wildly successful and takes over the 
way people do GenServers then there could maybe be an argument for 
including it in the language, but given that exception driven control flow 
is indeed considered an anti-pattern most of the time, and that you can 
implement this outside the language, it seems premature to push for 
inclusion at this time.

On Monday, April 25, 2022 at 4:52:27 PM UTC-4 eliasd...@gmail.com wrote:

> It would be cool to have the possibility to be able to use exceptions as 
> control flow for successful GenServer responses
>
> I'm sure there is the opinion that this is anti-pattern, but having the 
> possibility could really simplify some handler functions scenarios where 
> you need to validate a lot of different entries
>
> Having guard clauses to validate things could help
>
> ```
> if a > b, do: reply! :some_error, state
> ```
>
> In practice it would be something like this:
>
> --
>
> # We could have a GenResponse module that acts as a Exception
> ```
> defmodule GenResponse do
>   defexception [:res, :new_state, :value, :extra]
> end
>
> # All GenServer handle functions would need to have a exception wrapper in 
> compile time, this could maybe be configured with something like:
> # > use GenServer, exception_flow: true
> try do
>   # Could be used directly like this
>   raise GenResponse, res: :noreply, new_state: :any
>
>   # Or also like this
>   noreply! :any
> rescue
>   # Essentially, in every handle function something like this would be 
> under the hood
>   res in GenResponse -> 
> case res do
>   %GenResponse{res: :noreply, new_state: state} -> 
> {:noreply, state}
>
>   %GenResponse{res: :reply, value: value, new_state: state} -> 
> {:reply, value, state}
> end
> end
> ```
>
>
>
>
>

-- 
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/7301dab0-2ed8-489e-ba10-ac36fbfd7d1bn%40googlegroups.com.


Re: [elixir-core:10851] [Proposal] - Add an option to deps.get to force failure on lock mismatch

2022-04-01 Thread Ben Wilson
Yup, I also see the value in a human check. I think it's analogous to `mix 
format --checked` where the option explicitly exists to allow systems to 
enforce expectations.

+1 from me.

On Friday, April 1, 2022 at 1:51:12 PM UTC-4 ma...@jonrowe.co.uk wrote:

> If I'm understanding the original post correctly its a check for 
> preventing human error, e.g. they've run an update or a get but forgotten 
> to check in the changes to `mix.lock`, it's not something that needs to be 
> a default because that works fine, but just a nicety to prevent dirty 
> source code checkouts in a CI environment.
>
> Personally I don't see the harm in that, its just an improvement for 
> developer experience in setting up CI, I could equally see that this could 
> be moved to "well your ci should fail if you care about that" (it wouldn't 
> be that hard to write a step after `mix deps.get` that checked the file 
> hadn't changed). Overall if its easy for mix to do I'd say "why not", if 
> its problematic due to implementation reasons and would cause additional 
> maintenance burden I'd be ok to say "yeah nah".
>
> Just my 2¢.
>
> Cheers
> Jon
>
> On Wed, 30 Mar 2022, at 4:43 PM, Austin Ziegler wrote:
>
> This feels like something that either isn’t needed or should be the 
> default behaviour, not an opt-in.
>
> Where I feel it may not be needed is because if there is a mismatch while 
> I am developing, it is a *deliberate* change that I have made and want 
> the implicit update behaviour. It also only happens if there’s a version 
> mismatch (e.g., the mix.exs file contains *~> 3.2* but the mix.lock file 
> is *3.1.2*). Otherwise, mix.lock is frozen. That is, if mix.exs contains *~> 
> 3.2* and the mix.lock is *3.2.2* but *3.5.2* is available, there will not 
> be an update applied.
>
> Where I feel it may be better as the default behaviour is that I think 
> that mix deps.get --update-changed might be better as you explicitly tell 
> the tooling that you expect an update.
>
> I’m not happy in the Node ecosystem that you have to use npm ci or yarn 
> install --frozen-lockfile in order to not have volatile lockfiles. The 
> behaviour in the Node ecosystem is that a transitive dependency *may* update 
> with a normal npm install or yarn install.
>
> -a
>
>
> On Wed, Mar 30, 2022 at 10:31 AM Luis Guilherme  
> wrote:
>
> If dependencies in the mix.lock do not match those in mix.exs, *mix 
> deps.get --strict* will exit with an error, instead of updating the 
> mix.lock file.
>
> This is inspired by npm ci 
> 
>  and 
> aims to solve a rather common problem of people updating mix.exs but 
> forgetting to update the mix.lock file.
>  (there are non-obvious situations if you have path dependencies, where 
> updating a dependency version will cascade to every other mix project using 
> it)
>
> npm ci is used on the official github action 
>  
> for node.js and I think it would be nice to use mix deps.get --strict on 
> the elixir one as well
>
>
> -- 
> 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/8918d9ca-2fcb-4abd-b28e-f7bf2a00ead1n%40googlegroups.com
>  
> 
> .
>
>
>
> -- 
> Austin Ziegler • halos...@gmail.com • aus...@halostatue.ca
> http://www.halostatue.ca/ • http://twitter.com/halostatue
>
>
> -- 
> 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/CAJ4ekQugHWnXrhtjPkipgbvPy%3DWzWWpzKLi7WCrJT3d_4AuJ3A%40mail.gmail.com
>  
> 
> .
>
>
>

-- 
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/02c62eb1-e75c-404a-9ecd-ae2d7165eaacn%40googlegroups.com.


Re: [elixir-core:10833] [Proposal] Add `List.pop/2`

2022-03-08 Thread Ben Wilson
I would benchmark to make sure that you're actually gaining something. If 
you are relying on it to be small, then at that specific size a list might 
also just be fine, and you won't be relying on behavior that could change 
in a future release.

On Monday, March 7, 2022 at 11:49:06 AM UTC-5 Max Veytsman wrote:

> For what it's worth, I use MapSets for these kinds of autocompletion 
> suggestion lists in LiveView. It's worth noting that these aren't 
> guaranteed to preserve insertion order, and I'm relying on a implementation 
> detail that they will for a small number of keys.
>
> On Mon, Mar 7, 2022 at 10:51 AM h...@nathanmlong.com  
> wrote:
>
>> Hmm. I can't give too much detail, but the basic context is a LiveView 
>> form where the user selects some ports and the form provides suggestions as 
>> they type. Eg, if they type `2` it will suggest `22 - SSH`, `25 - SMTP`, 
>> etc.
>>
>> The currently-selected ports are a list of integers. If `22` is already 
>> selected, the LiveView won't suggest it. So if the LiveView gets a message 
>> to deselect `22`, it tries to pop it out of the `selections` list. If the 
>> pop succeeds, the `suggestions` list can be updated to include port `22` 
>> again. If the pop doesn't succeed, we can ignore the message; we can't 
>> deselect a port that wasn't selected to start with.
>>
>> I can't combine `selected` and `suggested` (eg by flagging the 
>> suggestions which are also selected) because both collections can contain 
>> elements that the other doesn't contain; the user may select ports that are 
>> not in the suggestions list. And it's not practical to have a top-level 
>> list of every possible port and flag each as `selected`, `suggested`, or 
>> both, because there are are 65,535 possible ports.
>>
>> So the core of my use case is: I get a user message to remove an item 
>> from a list, and after attempting to remove it, I want to take a follow-up 
>> action only if the item was was actually in the list.
>>
>> On Friday, March 4, 2022 at 11:05:35 AM UTC-5 José Valim wrote:
>>
>>> Hi Nathan, thanks for the email. Can you please show some examples of 
>>> where they could be handy with some context around them? Thank you!
>>>
>>> On Fri, Mar 4, 2022 at 3:45 PM h...@nathanmlong.com <
>>> h...@nathanmlong.com> wrote:
>>>
 This is a modified version of what I proposed in 
 https://github.com/elixir-lang/elixir/pull/11681

 Similar to `Map.pop/2` and and `Keyword.pop/2`, I propose adding 
 `List.pop/2`.

 I also propose adding `List.find_and_pop/2`, which is more generalized 
 since it takes a function.

 Here are possible implementations.

 ```elixir
 @doc """
 Returns and removes the first value matching `item` in the `list`.

 ## Examples
iex> List.pop([1, 2, 2, 3], 2)
{2, [1, 2, 3]}
iex> List.pop([1, 2, 3, 4], 20)
{nil, [1, 2, 3, 4]}
 """
 def pop(list, item) do
   find_and_pop(list, &(&1 == item))
 end

 @doc """
 Returns and removes the first value matching `fun` in the `list`.

 ## Examples
iex> List.find_and_pop([1, 2, 3, 4], &(&1 > 2))
{3, [1, 2, 4]}
iex> List.find_and_pop([1, 2, 3, 4], &(&1 > 20))
{nil, [1, 2, 3, 4]}
 """
 def find_and_pop(list, fun) do
   case Enum.find_index(list, fun) do
 nil -> {nil, list}
 i -> pop_at(list, i)
   end
 end
 ```

 -- 
 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/bdc98b8c-fc73-40d7-8287-eb0b5d3ea97en%40googlegroups.com
  
 
 .

>>> -- 
>> 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/57bc38e4-2596-415c-8dbf-a235330d459an%40googlegroups.com
>>  
>> 
>> .
>>
>

-- 
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/fa78cd65-804d-4160-99fb-58d0e0994ddan%40googlegroups.com.

Re: [elixir-core:10725] Re: Wrapper for receive block.

2022-01-24 Thread Ben Wilson
For that purpose, I feel like:

{:ok, %{pattern: [match, here]}} = Foo.await(item)

would work right? Can you help me understand why the patterns themselves 
need to be passed to your `await` function?

On Monday, January 24, 2022 at 12:09:56 PM UTC-5 mateus...@swmansion.com 
wrote:

> Hi there,
>
> we're preparing a message-based API as well, so one can use `receive` or 
> `handle_info` when needed. However, we expect that functionality to be used 
> mostly in elixir scripts/livebooks, where `await` is going to cover the 
> majority of cases, saving us from having `receive` blocks everywhere. It 
> can be also compared to `Task.await`, which has similar problems to what 
> you described, yet it proves useful in particular situations. Another point 
> is that extracting variables from a match can be used in many other 
> scenarios and currently it requires hundreds of lines of code to implement 
> properly AFAIK :P
>
> Regards,
> Mateusz
>
> poniedziałek, 24 stycznia 2022 o 14:56:55 UTC+1 José Valim napisał(a):
>
>> Honestly, I am not sure if it is worth encapsulating the event as you 
>> propose compared to a receive. For example, what happens if you want to 
>> receive at least one message from two distinct pipelines? What happens if 
>> you are inside a GenServer, where any receive pattern can be harmful and 
>> handle_info should be preferred?
>>
>> The main reason "assert_receive" exists is not because of the 
>> convenience, but rather the improved error message. And those scenarios are 
>> less common too (at least you are not running a test inside a GenServer).
>>
>> On Mon, Jan 24, 2022 at 2:50 PM Andrzej Podobiński <
>> andrzej.p...@swmansion.com> wrote:
>>
>>> Hi,
>>> thanks for your interest! I'm working on a specific pipeline in the 
>>> Membrane framework. The API of this pipeline allows the user to subscribe 
>>> for events that this pipeline emits, and then synchronously wait for these 
>>> events. The idea is to provide a macro that wraps the receive block to make 
>>> waiting for the event nicer to the user - just like assert_receive. 
>>>
>>> https://github.com/membraneframework/membrane_core/blob/remote-controlled-pipeline/lib/membrane/remote_controlled/pipeline.ex#L55
>>> ps. I'm aware that the current implementation of "await" I've linked 
>>> won't work because of e.g. lack of macro expansion.
>>> niedziela, 23 stycznia 2022 o 18:58:14 UTC+1 hunter...@gmail.com 
>>> napisał(a):
>>>
 Hi,

 I'm wondering what sort of code you're trying to write where a receive 
 ... after block wouldn't work well in this situation. Furthermore what do 
 we do in the error case if the receive times out? For ExUnit this is quite 
 simple: the test fails, but in your application code this doesn't mean 
 anything. If you get to the point that you're specifying control from with 
 this new macro then you've just recreated receive with more steps. Could 
 you provide some code samples for what you're trying to achieve?

 Best,
 Theron
 On Thursday, January 20, 2022 at 9:22:43 AM UTC-6 
 andrzej.p...@swmansion.com wrote:

> Lastly, I was trying to implement a macro with similar functionality 
> as assert_receive from ExUnit. The purpose of this macro was to allow the 
> user to wait synchronously for a message specified by a pattern. The 
> given 
> pattern may contain variables that the user is interested to extract from 
> the arrived message (exactly as in ExUnit.assert_receive). I've noticed 
> that there is a significant amount of code that expands the given pattern 
> and then collects the variables from it etc. in order to properly extract 
> variables from the pattern. I have a feeling that it is not a valid 
> solution to use an ExUnit.assert_receive in the production code, so maybe 
> it would be possible to add the function of similar functionality to the 
> Process module. Something like Process.await_message(). Another possibly 
> better solution could be adding some functionality to the Macro module 
> that 
> would cover expanding the macro and collecting variables etc. (
> https://github.com/elixir-lang/elixir/blob/a64d42f5d3cb6c32752af9d3312897e8cd5bb7ec/lib/ex_unit/lib/ex_unit/assertions.ex#L467
> )
>
> -- 
>>> 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/86836f06-f926-42de-aed0-9576d836b61cn%40googlegroups.com
>>>  
>>> 
>>> .
>>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"elixir-lang-core" g

Re: [elixir-core:10716] [Proposal] Add a shortcut to access a struct within the module where it is defined

2022-01-21 Thread Ben Wilson
__MODULE__ is the right answer here IMHO. It is consistent with the other 
"meta constants" like __ENV__, __DIR__ __FILE__ and so on in that they 
desugar to constants, but are file / code relative. It isn't a super common 
pattern, but last time I checked generated phoenix code does a 
%__MODULE__{} pattern match check on the changeset functions.

On Friday, January 21, 2022 at 6:56:42 AM UTC-5 ins...@gmail.com wrote:

> Thanks for the tip Wojtek
> Aliasing __MODULE__ should work in my case
>
> As far as I understand this pattern isn't used too often(at least projects 
> like Plug or Ecto don't use it), so I guess it is not really considered as 
> idiomatic 
>
> I just feel that if you are inside a module there should be a shortcut 
> built-in in the language(like when you call other functions from the module 
> you don't specify the full path) but it might be just old instincts from 
> other languages
>
> пʼятниця, 21 січня 2022 р. о 10:58:56 UTC Wojtek Mach пише:
>
>> Neither `%_{}` nor `%self{}` can be supported because they already have a 
>> meaning in pattern matches. The former means _any_ struct and the latter 
>> binds the matched struct name to the variable `self`.
>>
>> You can give `__MODULE__` another name with an alias:
>>
>> alias __MODULE__, as: Struct
>>
>> def connect(%Struct{} = channel)
>>
>>
>> On January 21, 2022, "gmail.com"  wrote:
>>
>> It is common to define a struct together with various functions that 
>> access that struct in the module:
>>
>> defmodule Chat.Channel do
>>   defstruct name: "", public?: true
>> 
>>   def new do
>> %Chat.Channel{name: "Untitled"}
>>   end
>>
>>   def connect(%Chat.Channel{} = channel) do
>> IO.inspect(channel)
>>   end
>> end
>>
>> It is also common to alias the struct for easier access
>>
>> defmodule Chat.Channel do
>>   defstruct name: "", public?: true
>> 
>>   alias Chat.Channel
>>   
>>   # ...
>> end
>>
>> But, say, renaming the module would require manually replacing all struct 
>> occurrences with the new module name. Aliasing can help, but if the last 
>> bit should be updated too(say Chat.Channel should be updated to Chat.Room) 
>> it would still require to manually replace everything.
>>
>> There is a workaround to use __MODULE__, but IMO the code looks a bit ugly
>>
>> defmodule Chat.Channel do
>>   defstruct name: "", public?: true
>> 
>>   def new do
>> %__MODEUL__{name: "Untitled"}
>>   end
>> 
>>   def connect(%__MODEUL__{} = channel) do
>> IO.inspect(channel)
>>   end
>> end
>>
>> I think It would be great to have some kind of shortcut(syntactic sugar) 
>> to access the struct within the module.
>> First I thought about something like %_(%%, %. etc) but this way it looks 
>> a bit cryptic 
>>
>> def connect(%_{} = channel) do
>>
>> So maybe something like %self would work
>>
>> defmodule Chat.Channel do
>>   defstruct name: "", public?: true
>> 
>>   def new do
>> %self{name: "Untitled"}
>>   end
>> 
>>   def connect(%self{} = channel) do
>> IO.inspect(channel)
>>   end
>> end
>>
>> What do you think?
>>
>>  -- 
>>  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/da49bf41-d4ad-4fc7-a88c-1338e7a463c1n%40googlegroups.com
>>  
>> 
>> .
>>
>>

-- 
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/b473f840-3e6e-43d5-b71b-280bb02b55f4n%40googlegroups.com.


Re: [elixir-core:10648] Introduce let and reduce qualifiers to for

2021-12-20 Thread Ben Wilson
To revisit the example situation from the original post:

```
{sections, _acc} =
for let {section_counter, lesson_counter} = {1, 1}, section <- sections do
lesson_counter = if section["reset_lesson_position"], do: 1, else: 
lesson_counter
{lessons, lesson_counter} = for let lesson_counter, lesson <- 
section["lessons"] do
{Map.put(lesson, "position", lesson_counter), lesson_counter + 1}
end
section =
section
|> Map.put("lessons", lessons)
|> Map.put("position", section_counter)

{section, {section_counter + 1, lesson_counter}}
end
```

I think that's nice! It focuses on inputs and outputs and reduces the 
overall line noise.

On Monday, December 20, 2021 at 5:28:29 PM UTC-5 José Valim wrote:

> Stefan, this would work if we include all extensions:
>
> for reduce {status, acc} = {:ok, []}, status == :ok, foo <- foos do
>   case barify(foo) do
> {:ok, bar} -> {:ok, [bar | acc]}
>
> {:error, _reason} = error -> error
>   end
> end
>
> I am not sure if you find it any better. It is hard to do this with "let" 
> because you don't want to include the element of when it fails.
>
> On Mon, Dec 20, 2021 at 9:23 PM Stefan Chrobot  wrote:
>
>> I went through some of our code and one thing I'd love to see is a way to 
>> replace Enum.reduce_while with the for comprehension. So the code like this:
>>
>> Enum.reduce_while(foos, {:ok, []}, fn foo, {:ok, bars} ->
>>   case barify(foo) do
>> {:ok, bar} -> {:cont, {:ok, [bar | bars]}}
>> {:error, _reason} = error -> {:halt, error}
>>   end
>> end)
>>
>> Would the following even work?
>>
>> for reduce(result = {:ok, []}), foo <- foos, {:ok, _} <- result do
>>   case barify(foo) do
>> {:ok, bar} -> {{:ok, [bar | bars]}}
>> {:error, _reason} = error -> {error}
>>   end
>> end
>>
>> Even if it did, it's not doing a great job of communicating the intent 
>> and still potentially requires a Enum.reverse call. The intent here is 
>> "early exit with some value upon some condition or pattern mismatch".
>>
>>
>> Best,
>> Stefan
>>
>> pon., 20 gru 2021 o 21:06 Stefan Chrobot  napisał(a):
>>
>>> I really like this proposal! For me it strikes the perfect balance 
>>> between terseness and explicitness that I've come to enjoy in Elixir.
>>>
>>> My votes:
>>> - Naming: let over given; just because it's shorter,
>>> - Do use parents: let "feels" similar to var!.
>>>
>>> Best,
>>> Stefan
>>>
>>> pon., 20 gru 2021 o 19:54 José Valim  napisał(a):
>>>
 Good point. I forgot to mention the :reduce option will be deprecated 
 in the long term.

 On Mon, Dec 20, 2021 at 7:53 PM 'eksperimental' via elixir-lang-core <
 elixir-l...@googlegroups.com> wrote:

> The proposal is very concise,
> the only thing that would be problematic is the use of `reduce` for two
> different things,
>
> for <>, x in ?a..?z, reduce: %{} do
>   acc -> Map.update(acc, <>, 1, & &1 + 1)
> end
>
> {sum, count} =
>   for reduce({sum, count} = {0, 0}), i <- [1, 2, 3] do
> sum = sum + i
> count = count + 1
> {sum, count}
>   end
>
> It would lead to misunderstanding as it may not be clear which one we
> are talking about when we say "use for reduce"
>
>
>  On Mon, 20 Dec 2021 19:11:54 +0100
> José Valim  wrote:
>
> > Hi everyone,
> > 
> > This is the second proposal for-let. You can find it in a gist:
> > https://gist.github.com/josevalim/fe6b0bcc728539a5adf9b2821bd4a0f5
> > 
> > Please use the mailing list for comments and further discussion.
> > Thanks for all the feedback so far!
> > 
>
> -- 
> 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/61c0d119.1c69fb81.af520.c181SMTPIN_ADDED_MISSING%40gmr-mx.google.com
> .
>
 -- 
 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/CAGnRm4LOyoAmXULJQo%2BYX4eFVJZJAoYtKHytoHujCS_kJ6AEuA%40mail.gmail.com
  
 
 .

>>> -- 
>> 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-l

[elixir-core:10641] Re: Introduce let and reduce qualifiers to for

2021-12-20 Thread Ben Wilson
I believe this nicely addresses my concerns from the first proposal. Inner 
refactoring into functions is 100% possible, and there are no strange 
reassignment behaviors introduced that don't extend to the rest of the 
language. As for the questions outlined in the guide:

1) To Paren or not Paren: Parens optional is best IMHO.
2) Naming for let: I like let.
3) Naming for reduce: I don't _love_ reduce but I think it's the best. It 
is also no worse than Enum.reduce. Both are basically "for | Enum" 
(indicating we are dealing with a collection) "reduce" ok into a single 
managed value.
4) Limitations to patterns right now: I'm 100% with limiting let to `let 
var` or `let {tuple, of, vars}` for now. This can always be relaxed later.

All in all, very happy with where this proposal has landed, and tantalized 
by the future possibilities!

On Monday, December 20, 2021 at 1:18:24 PM UTC-5 Dunya Kirkali wrote:

>
> This guide is super useful. Maybe we should use it to update the docs?
> On Monday, December 20, 2021 at 7:12:09 PM UTC+1 José Valim wrote:
>
>> Hi everyone,
>>
>> This is the second proposal for-let. You can find it in a gist: 
>> https://gist.github.com/josevalim/fe6b0bcc728539a5adf9b2821bd4a0f5
>>
>> Please use the mailing list for comments and further discussion. Thanks 
>> for all the feedback so far!
>>
>

-- 
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/0c3c0ab5-b9a7-412b-aed8-43ea6efc05a8n%40googlegroups.com.


[elixir-core:10601] Re: Introduce :let in for-comprehensions

2021-12-16 Thread Ben Wilson
I am with Louis and Paul so far I think. I won't repeat their comments but 
I think I can extend the issue by pointing out that this breaks refactoring 
for the inner contents of `for`. Previously, if you have:

```
  for lesson <- section["lessons"], reduce: 0 do
counter ->
  # complex multi-line-thing using the lesson and counter
  end 
```

I can refactor this into:

```
  for lesson <- section["lessons"], reduce: 0 do
counter ->
  complex_operation(lesson, counter)
  end 

  def complex_thing(lesson, counter) do
# complex multi-line-thing using the lesson and counter
  end
```

And everything just works, as is normal in Elixir code. The proposed 
changes would (as far as I can see) break this and that feels very 
unexpected and foreign.

I sympathize with the problem space, but so far it's a -1 for me on this 
particular proposed improvement.

- Ben
On Thursday, December 16, 2021 at 10:02:49 AM UTC-5 José Valim wrote:

> Note: This proposal contains images and rich text that may not display 
> correctly in your email. If so, you can read this proposal in a gist 
> .
>
> There is prior art in languages like Common Lisp, Haskell, and even in C# 
> with LINQ on having very powerful comprehensions as part of the language. 
> While Elixir comprehensions are already very expressive, allowing you to 
> map, filter, reduce, and collect over multiple enumerables at the same 
> time, it is still not capable of expressing other constructs, such as 
> map_reduce.
>
> The challenge here is how to continue adding more expressive power to 
> comprehensions without making the API feel massive. That's why, 7 years 
> after v1.0, only two new options have been added to comprehensions, :uniq 
> and :reduce, to a total of 3 (:into, :uniq, and :reduce).
> Imperative loops 
>
> I have been on the record a couple times saying that, while many problems 
> are more cleanly solved with recursion, there is a category of problems 
> that are much more elegant with imperative loops. One of those problems 
> have been described in the "nested-data-structures-traversal" 
>  
> repository, with solutions available in many different languages. Please 
> read the problem statement in said repository, as I will assume from now on 
> that you are familiar with it.
>
> Personally speaking, the most concise and clear solution is the Python 
> one, which I reproduce here:
>
> section_counter = 1lesson_counter = 1
> for section in sections:
> if section["reset_lesson_position"]:
> lesson_counter = 1
>
> section["position"] = section_counter
> section_counter += 1
>
> for lesson in section["lessons"]:
> lesson["position"] = lesson_counter
> lesson_counter += 1
>
> There are many things that make this solution clear:
>
>- Reassignment
>- Mutability
>- Sensitive whitespace
>
> Let's compare it with the Elixir solution I wrote and personally prefer 
> .
>  
> I am pasting an image below which highlights certain aspects:
>
> [image: Screenshot 2021-12-13 at 10 02 48] 
> 
>
>- 
>
>Lack of reassignment: in Elixir, we can't reassign variables, we can 
>only rebind them. The difference is, when you do var = some_value 
>inside a if, for, etc, the value won't "leak" to the outer scope. This 
>implies two things in the snippet above:
>1. We need to use Enum.map_reduce/3 and pass the state in and out 
>   (highlighted in red)
>   2. When resetting the lesson counter, we need both sides of the 
>   conditional (hihhlighted in yellow)
>- 
>
>Lack of mutability: even though we set the lesson counter inside the 
>inner map_reduce, we still need to update the lesson inside the 
>session (highlighted in green)
>- 
>
>Lack of sensitive whitespace: we have two additional lines with end in 
>them (highlighted in blue)
>
> As you can see, do-end blocks add very litte noise to the final solution 
> compared to sensitive whitespace. In fact, the only reason I brought it up 
> is so we can confidently discard it from the discussion from now on. And 
> also because there is zero chance of the language suddenly becoming 
> whitespace sensitive.
>
> There is also zero chance of us introducing reassignment and making 
> mutability first class in Elixir too. The reason for this is because we all 
> agree that, the majority of the time, lack of reassignment and lack of 
> mutability are features that make our code more readable and understandable 
> in the long term. The snippet above is one of the few examples where we are 
> on the wrong end of the trade-offs.
>
> Therefore, how can we move forward?
> 

[elixir-core:10421] Re: Proposal: built-in DynamicSupervisor partitioning

2021-09-02 Thread Ben Wilson
Implemented this way, options like max_restarts max_children and so on 
would occur per partition. I take it the plan would be to simply note that 
in the docs? I don't see any easy way to enforce those values across all 
partitions, which I think is just fine.

which_children/1 and so on won't work as expected either, so maybe we want 
a helper function inside of DynamicSupervisor that flat_maps that over the 
child supervisors?

Overall though, +1 from me.

On Thursday, September 2, 2021 at 11:28:19 AM UTC-4 José Valim wrote:

> Given supervisors are also processes, they may also become bottlenecks. 
> While this is unlikely to happen to a Supervisor, since it is mostly 
> static, it can happen to a DynamicSupervisor.
>
> We can address this by partitioning the dynamic supervisor. Imagine the 
> following dynamic supervisor:
>
> defmodule MyApp.DynamicSupervisor do
>   use DynamicSupervisor
>
>   def start_link(opts) do
> DynamicSupervisor.start_link(__MODULE__, arg, opts)
>   end
>
>   def init(_arg) do
> DynamicSupervisor.init(strategy: :one_for_one)
>   end
> end
>
> In order to partition it, we can start 8 instances of said supervisor 
> inside a regular Supervisor, and then pick one partition at random when 
> starting a child. For example:
>
> defmodule MyApp.Supervisor do
>   use Supervisor
>
>   @partitions 8
>   @name __MODULE__
>
>   def start_child(module, arg) do
> i = :erlang.phash2(self(), @partitions) + 1
> DynamicSupervisor.start_child(:"#{__MODULE__}#{i}", {module, arg})
>   end
>
>   def start_link do
> Supervisor.start_link(__MODULE__, arg, name: @name)
>   end
>
>   def init(arg) do
> children =
>   for i <- 1..@partitions do
> name = :"#{__MODULE__}#{i}"
> Supervisor.child_spec({MyApp.DynamicSupervisor, name: name}, id: 
> name)
>   end
>
> Supervisor.init(children, strategy: :one_for_one)
>   end
> end
>
> I would like to make the above more convenient by introducing a 
> :partitions option to DynamicSupervisor.start_link. When given, the new 
> option will automatically start N dynamic supervisors under a supervisor, 
> like above:
>
> DynamicSupervisor.start_link(__MODULE__, :ok, partitions: 8, name: @name)
>
> For now, the :name option will be required.
>
> Now, when spawning child processes, you will use via tuples:
>
> DynamicSupervisor.start_child({:via, DynamicSupervisor, {@name, self()}}, 
> {module, arg})
>
> The via tuple has the format {:via, DynamicSupervisor, {supervisor_name, 
> value_to_partition_on}}. Once invoked, it will take care of partitioning 
> based on the current process and dispatching it.
>
> Overall, encapsulating the partitioning of DynamicSupervisor (and 
> consequently of Task.Supervisor) into an easy to use API can help to 
> vertically scale up applications that use those constructs.
>
> ## Open questions
>
> One of the confusing aspects of the above is that the :name option no 
> longer reflects the name of the DynamicSupervisor but of the parent 
> Supervisor. One alternative is to *not* accept the :name option when 
> :partitions is given, instead we could have a :root_name option instead (or 
> something more appropriately named).
>
> Implementation wise, we will store the available processes in ETS or using 
> a Registry (to be started alongside the Elixir application).
>
> Feedback?
>

-- 
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/bae8be24-a2e5-4a07-89db-7758ccfaf0d4n%40googlegroups.com.


Re: [elixir-core:10200] Proposal: Warn on duplicated specs

2021-04-05 Thread Ben Wilson
Right, and this is why I think Jose is arguing that this is a job for 
Dialyzer. The only way to know that two specs are duplicate is if they are 
logically duplicate. Elixir does not know about the logic of specs today, 
that's dialyzer's job. eg:

@type one :: 1
@spec foo(1) :: "one"
@spec foo(one) :: "one"

This is logically duplicate, but not AST level duplicate. You could special 
case things I suppose at the Elixir level and only care about AST level 
duplicates but this leaves out a lot of cases people probably care about:

@spec age(user :: %User{}) :: integer
@spec age(current_user :: %User{}) :: integer

Here we have specs that are basically duplicates, but there is a difference 
in the argument name.
On Monday, April 5, 2021 at 9:53:47 AM UTC-4 eksperimental wrote:

> On Mon, 5 Apr 2021 09:48:21 -0400
> Allen Madsen  wrote:
>
> > @spec foo(1) :: "one"
> > @spec foo(2) :: "two"
> > def foo(1), do: "one"
> > def foo(2), do: "two"
>
> Yes, but those would not be duplicated.
> These would, and Dialyzer will error saying that "foo/1 has overlapping
> domains"
>
> @spec foo(1) :: "one"
> @spec foo(1) :: "one"
> @spec foo(2) :: "two"
> def foo(1), do: "one"
> def foo(2), do: "two"
>

-- 
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/07d5bebf-e59b-40e3-abd6-299229c3e764n%40googlegroups.com.


Re: [elixir-core:10160] Ranges with steps

2021-03-22 Thread Ben Wilson
The 1..9//2 structure feels like the best of the presented options to me. I 
think it reads well out loud, since .. often means "to" and / is often 
rendered as "by" so that would read 1 to 9 by 2.

To make sure I'm clear about the semantics: If I have:

```
1..x//1 |> Enum.to_list
```

Then if `x` is zero or less than zero, I get an empty list? This would 
definitely be nice, we've been bitten by the exact scenarios mentioned in 
the first post.
On Monday, March 22, 2021 at 10:26:13 AM UTC-4 am...@binarynoggin.com wrote:

> Yes, the `1..9//2` communicates intention a little better than `a..b..c` 
> IMO.
>
> Amos King, CEO
>
>     
>   
>    
> 
>
> 573-263-2278 <(573)%20263-2278> am...@binarynoggin.com
>
>
> On Mon, Mar 22, 2021 at 9:05 AM José Valim  wrote:
>
>>  
>>
>>> I still find the syntax to be confusing with the step as the last 
>>> element. I really wish that we could do something like `a..b by: 3` but 
>>> that comes with other implementation issues. I like the proposals using a 
>>> different operator for the step. `a..b\\c`?
>>>
>>
>> Unfortunately a..b\\c is ambiguous because \\ is used as default 
>> arguments. So you could do "a..b\\1..3". It is semantically unambiguous in 
>> this case, but definitely syntactically ambiguous.
>>
>> Here are some approaches of what we could allow. I am considering they 
>> all represent the range from 1 to 9 by 2 and from 9 to 1 by -1:
>>
>>- 1..2..9 and 9..-1..1 - as someone proposed, maybe having the step 
>>in the middle is clearer
>>
>>- 1..9//2 and 9..1//-1 - note // is generally ambiguous in Elixir 
>>because of the capture operator. So this will only work if ..// is 
>> defined 
>>as a ternary operator. This means we will likely introduce the atom :..// 
>>and the capture operator would be &..///3. I think those are acceptable 
>>trade-offs, but worth mentioning.
>>
>>- Combinations with \ and /:
>>- 1..9/\2 and 9..1/\-1
>>   - 1..9*\2 and 9..1*\-1
>>   - 1..9\/2 and 9..1\/-1
>>   - 1..9*/2 and 9..1*/-1
>>   
>>   - 1..9^^2 and 9..1^^-2
>>
>> To be honest, I like the first two. One nice bonus about 1..9//2 is 
>> because we can actually think that it is cutting the number of elements in 
>> 2, by some approximation. 1..8//1 has 8 elements. 1..8//2 has 4. :)
>>
>> -- 
>> 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/CAGnRm4JNXVDdJG%3DJ2MuiiN9%2BxHNUm58%2Bi%3DAbPygGkZm6sZ4jEA%40mail.gmail.com
>>  
>> 
>> .
>>
>

-- 
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/cfc0db92-7165-41dc-9241-8c9d6ef3a026n%40googlegroups.com.


Re: [elixir-core:10121] [Proposal] range pattern matching in case without when

2021-03-15 Thread Ben Wilson
I think eksperimental was dead on when he said what you really want is 
`cond`.

```
cond do
val in ?a..?z
val in ?A..?Z
```

Changing `case` to have an implicit `where` in certain special cases is 
going to make it behave inconsistently compared to other places that take 
patterns. Optimizing the characters for this specific case isn't worth the 
implicit magic ImHO.

On Sunday, March 14, 2021 at 10:15:06 AM UTC-4 computador...@gmail.com 
wrote:

> I understand, how about it?
>
> case ?a do
>   in ?a..?z -> # code
>   in ?A..?Z -> # code
>   _ -> # code
> end
>
> Goiás ou Vila Nova?
>
> Em sábado, 13 de março de 2021 às 09:46:56 UTC-3, José Valim escreveu:
>
>> Thanks for the proposal,
>>
>> However, ?a..?z in a pattern should match on a range from ?a..?z. 
>> Similarly, x..y can be used to match on any range and extract its values.
>>
>> Those are all valid and correct today, and introducing this proposal 
>> would break said semantics.
>>
>> On Sat, Mar 13, 2021 at 13:44 Amos King  wrote:
>>
>>> Would this match on an element in a range and on an equivalent range? ?a 
>>> or ?a..?z would both match with ?a..?z
>>>
>>> The proposed code looks nice and I thought was simpler at first. 
>>> Considering it further made me think of the situation above. I want the 
>>> explicitness of the current behavior to reduce the ambiguity.
>>>
>>> Amos King
>>> CEO
>>> Binary Noggin
>>>
>>> On Mar 13, 2021, at 06:26, Igor Silva  wrote:
>>>
>>> Current behavior
>>>
>>>
>>>
>>> case ?a do
>>>   x when x in ?a..?z -> # code
>>>   x when x in ?A..?Z -> # code
>>>   _ -> # code
>>> end
>>>
>>> Desired behavior
>>>
>>> case ?a do
>>>   ?a..?z -> # code
>>>   ?A..?Z -> # code
>>>   _ -> # code
>>> end
>>>
>>> #GoiásouVilaNova
>>>
>>> -- 
>>> 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/61ea5a90-6e3b-49a0-ad58-377959dd6aabn%40googlegroups.com
>>>  
>>> 
>>> .
>>>
>>> -- 
>>> 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/F40F773D-8636-4040-826A-D75EF9C35734%40binarynoggin.com
>>>  
>>> 
>>> .
>>>
>>

-- 
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/d6ede81a-c490-4892-bfb0-4e5fbe7435f5n%40googlegroups.com.


Re: [elixir-core:9984] [Proposal] Make Kernel.tap/2 and Kernel.then/2 macros

2021-01-17 Thread Ben Wilson

Unfortunately it cannot do this in all cases:

fun = &IO.inspect/1

foo
|> tap(fun)
|> blah

`tap` as a macro has no ability to know whether `fun` is a function at 
compile time.
On Friday, January 15, 2021 at 1:54:58 PM UTC-5 Allen Madsen wrote:

> I meant compile time.
>
> Allen Madsen
> http://www.allenmadsen.com
>
>
> On Fri, Jan 15, 2021 at 1:53 PM Allen Madsen  wrote:
>
>> A macro should be able to tell if a function was passed in most cases at 
>> runtime.
>>
>> Allen Madsen
>> http://www.allenmadsen.com
>>
>>
>> On Fri, Jan 15, 2021 at 2:26 AM Fernando Tapia Rico  
>> wrote:
>>
>>> One benefit of implementing it with functions is the is_function 
>>> guards, which provide a better user experience in case of bad arguments :)
>>>
>>> On Friday, January 15, 2021 at 7:35:58 AM UTC+1 José Valim wrote:
>>>
 Alright, please send a pull request so we can also collect the feedback 
 of the rest of the Elixir team. :)

 On Fri, Jan 15, 2021 at 00:50 sabi...@gmail.com  
 wrote:

> Thanks Jose and Christopher for your replies!
>
> > I am worried making it a macro will signal to developers they need 
> to worry about these kinds of low-level optimizations, which is not 
> generally true!
>
> I agree this is a legitimate concern and I totally understand if you 
> prefer to keep this a function.
> I'm a bit biased because I spent some time lately on some low-level 
> optimizations, which are indeed not very representative of the typical 
> use 
> cases.
>
> I probably wouldn't even have thought about it if these functions 
> weren't part of Kernel, which seems to be made of many macros already 
> (searching for *(macro)* in the Kernel docs yield 58 results!).
> So it might not be such a strong signal in this particular case?
>
> > Devil's advocate, one (of many) reasons why dev's shouldn't need to 
> worry about these kinds of optimizations is because the language is 
> conscientious about doing them for devs!
>
> I think this is the main argument: if the idiomatic way is also the 
> most performant possible, you don't even have to think about it and to 
> choose between the two.
> But this thinking taken to an extreme could lead to much overkill 
> complexity, so the question I suppose is about whether it is relevant or 
> overkill in this particular case?
> I honestly wouldn't know :)
>
> Le vendredi 15 janvier 2021 à 05:21:33 UTC+9, christ...@gmail.com a 
> écrit :
>
>> > I am worried making it a macro will signal to developers they need 
>> to worry about these kinds of low-level optimizations, which is not 
>> generally true!
>>
>> Devil's advocate, one (of many) reasons why dev's shouldn't need to 
>> worry about these kinds of optimizations is because the language is 
>> conscientious about doing them for devs!
>>
> -- 
>
 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/1581c1d4-6d38-418d-ab3b-78c2fe3ed4a0n%40googlegroups.com
>  
> 
> .
>
 -- 
>>> 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/d462bbad-457b-4a6d-9180-03f5feff40b4n%40googlegroups.com
>>>  
>>> 
>>> .
>>>
>>

-- 
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/df13638a-741c-4fc9-b66b-9f5b7b945bdan%40googlegroups.com.


Re: [elixir-core:9576] Loading arbitrary packages during plain iex sessions

2020-06-15 Thread Ben Wilson
The issue is, those packages need to be compiled and in a specific order, 
how would that work? `hex` isn't a build tool, `mix` is.

On Monday, June 15, 2020 at 6:07:49 AM UTC-4, Simon St.Laurent wrote:
>
> I would love to see (some version of) both the original proposal and this 
> one.  They would make IEx a lot more useful.
>
> Thanks,
> Simon St.Laurent
> *Introducing Elixir*
>
> On Mon, Jun 15, 2020 at 5:15 AM Stefan Chrobot  > wrote:
>
>> This is a nice proposal, but I'd rather have this go all the way and 
>> allow me to pull Hex packages while maintaining the current IEx session, so 
>> something like:
>>
>> $ iex --hex
>> iex> Something.deps_get :some_http_client, "1.0.0"
>> iex> SomeHttpClient.get(...)
>>
>>
>> Best,
>>
>> Stefan
>>
>> pon., 15 cze 2020 o 10:47 Abdullah Esmail > > napisał(a):
>>
>>> Hello,
>>>
>>> I believe it would be extremely helpful to old and new elixir developers 
>>> to be able to try out packages without the need to create a whole project.
>>> Developers coming from different backgrounds (python, ruby, etc) are 
>>> used to getting into the interactive shell and just importing/requiring the 
>>> package they need and start playing with it.
>>>
>>> I don't know if this is technically possible with iex, but it would 
>>> definitely change how I work with elixir in general.
>>>
>>> Something like:
>>> iex --hex  
>>>
>>> Even if it takes longer to start, at least I could try those packages 
>>> without creating a dummy project and including those packages as 
>>> dependencies and then compiling everything.
>>> One command to rule them all.
>>>
>>> Maybe `iex --hex` could create a temporary dummy project behind the 
>>> scenes?
>>>
>>> For what it's worth, I'd be *very* willing to help work on implementing 
>>> this if it's going to happen.
>>>
>>> I apologize if this has been discussed or brought up before. I couldn't 
>>> find a similar topic.
>>>
>>> -- 
>>> 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-l...@googlegroups.com .
>>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/elixir-lang-core/40ef0ab9-7d92-4601-b445-de7c5796c046o%40googlegroups.com
>>>  
>>> 
>>> .
>>>
>> -- 
>> 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-l...@googlegroups.com .
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/elixir-lang-core/CACzMe7bTc_rfzwneWVruKYghGRePynjRAgXYXQGqTP_zon17hw%40mail.gmail.com
>>  
>> 
>> .
>>
>

-- 
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/d5609066-bfc8-4a7c-aaa2-0534ec8d9a2fo%40googlegroups.com.


[elixir-core:9478] Re: Proposal: IO.error/2

2020-05-12 Thread Ben Wilson
Perhaps you addressed this, but how would IO.error behave when not 
compiling things? How would it behave if you remote console into a running 
system and call IO.error?

On Monday, May 11, 2020 at 11:33:40 PM UTC-4, Dallin Osmun wrote:
>
> I understand at first glance this proposal might not seem necessary. I 
> wanted to give some insight into how I got here. I'd like to outline a 
> couple of the alternatives I tried and some of the issues I ran into while 
> doing so.
>
> As a reminder: the goal is to emit multiple error diagnostics during the 
> compilation step and fail the compilation.
>
> *Let's stick with `raise/1`*
> Everyone is already using raise to emit errors from macros. The compiler 
> diagnostic that is emitted from raise is missing a position but it does 
> have a stacktrace. While the original frame in that trace does point to 
> your macro, it probably still isn't the correct line. Take the following 
> pseudocode. raise will cause a stacktrace that points to `query` on line 1 
> when your actual error is on line 3. Currently, raise does not and cannot 
> know exactly where your error is.
>
> ```
> 1. query Thing do
> 2.   id
> 3.   error_here
> 4. end
> ```
>
> *So add `raise/2`*
> Maybe we enhance raise so it takes an optional stacktrace as a second 
> argument like IO.warn does. While I think this is a great idea, it doesn't 
> meet one of the two criteria above (emit multiple errors). For the record 
> though, I do think there are cases out there where rather than let your 
> macro get into an inconsistent state you would want to raise an error and 
> stop compilation. If we allowed a custom stacktrace to be passed in to 
> raise then the error diagnostic it emitted would be more useful.
>
> *Why not use IO.warn/2 with the `warnings_as_errors` flag?*
> This solution does indeed solve both my criteria: multiple errors are 
> emitted and the build fails. But the developer experience is not ideal:
> - I am forcing my users to add a compiler flag to their project. It's one 
> more thing to remember when using my library.
> - As a macro author I would like to emit both warnings and errors. If I 
> can only emit warnings (which are treated as errors) then I am unable to 
> distinguish between the two.
> - This forces ALL warnings in your project to be treated as errors which 
> may not be desirable in some cases.
>
> *How about IO.warn/2 and return a raise if you hit any warnings?*
> So let's imagine then that I use IO.warn to report all of my errors. If I 
> had to report any errors then I'll make my macro output an AST for `raise 
> "broken macro: check the logs"`. I don't have to force the 
> `warnings_as_errors` flag on my users this way and I am able to emit 
> multiple errors. But now the compilation is successful. I have to rely on 
> my users actually exercising their code or having a good test suite to find 
> out that the output of the macro isn't actually going to work.
>
>
> On Monday, May 4, 2020 at 5:37:14 PM UTC-6, Dallin Osmun wrote:
>>
>> I propose that we add `IO.error/2` which matches the signature of 
>> `IO.warn/2`. It emits error diagnostics/messages instead of warnings and it 
>> causes the compile step to finish with :error.
>>
>>
>> *Reasoning*
>>
>> Often when building a macro you'll do some validation and `raise` an 
>> error if something isn't right. This creates a poor experience for the 
>> person using the macro for two reasons:
>> 1. You can only raise one error at a time
>> 2. You don't get a good picture of where the error is because your whole 
>> editor turns red
>>
>> You can solve both of those problems by using `IO.warn/2`. You can emit 
>> multiple warnings in a single compile step and you can pass in a stacktrace 
>> which gets turned into a Compiler Diagnostic that in turn, creates good 
>> editor hints. But now the compilation succeeds and you're left in a bad 
>> state.
>>
>> I think it is useful to see multiple errors at a time because it shortens 
>> the feedback loop. It also gives more context and can help you realize 
>> where the root cause of your issue lies.
>>
>> I think it would be useful to have a function that shared the properties 
>> of `IO.warn/2` and `raise/1`:
>> - I can emit multiple messages during a single compilation run
>> - These messages are output as Compiler Diagnostic errors
>> - Invoking this function will ultimately cause the compilation step to 
>> result in an :error
>>
>>
>> *Examples*
>>
>> Today in Ecto Query, this snippet will cause the entire file to turn red 
>> because we mistakenly used sort_by instead of order_by.
>> query p in Product, sort_by: p.price
>>
>> Lets assume we forgot to load the :user type in this Absinthe Schema. We 
>> have two errors but only one gets displayed. Once again, the entire editor 
>> turns red. If instead we saw each line that referenced :user turn red it 
>> might remind us more quickly that we forgot to call `import_types 
>> MyApp.UserTypes`.
>> query name: "Query" do
>>   f

[elixir-core:9438] Re: Add a window function to Enum

2020-03-29 Thread Ben Wilson
Hi Adam,

I believe this functionality already exists in the form of this function 
and others with the "chunk" name. 
https://hexdocs.pm/elixir/Enum.html#chunk_every/2

- Ben

On Sunday, March 29, 2020 at 5:58:19 AM UTC-4, Adam Lancaster wrote:
>
> Hello,
>
> Elixir is great. The Enum module is super great. Could it be better with a 
> window function?
>
> I wrote a function recently that traverses an enumerable X at a time, 
> would it be suitable for core?
>
> This is my naive implementation so you can see what it does:
>
>
>   @doc"Traverse a list window_size at a time, passing the window to fun"
>   def window(enum, window_size, fun) do
> do_window(enum, window_size, fun, [])
>   end
>
>
>   def do_window([], window_size, fun, acc) do
> acc
>   end
>   def do_window(enum = [_| tail], window_size, fun, acc) do
> {head, _rest} = Enum.split(enum, window_size)
> new_acc = acc ++ [fun.(head)]
> do_window(tail, window_size, fun, new_acc)
>   end
>
> If so I'd love to contribute, might need guidance on performance 
> optimisations though.
>
> Best
>
> Adz
>

-- 
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/aee0ed70-da53-4c4c-adfe-07d0c9415563%40googlegroups.com.


[elixir-core:9429] Re: Proposal: Enum.pop_by/2

2020-03-24 Thread Ben Wilson
Hi Eric,

Whether or not this is functionally equivalent to split_with depends on how 
it handles non unique lists, eg:

Enum.pop_by([1,2,2,3], fn x -> x == 2 end)

If it returns
{2, [1, 2, 3]}
Then it is definitely at least different.

This almost seems better suited for the List module. Map and many other 
Enumerables already have a pop concept that would be a lot more efficient, 
and this specific approach seems very list centric.

On Tuesday, March 24, 2020 at 6:08:07 PM UTC-4, Eric Froese wrote:
>
> In my current project, I have an existing list of unique objects (A0), 
> and an updated representation of that list (A1).
>
> I need to group A1 into thee lists: {added, still_present, removed} by 
> comparing it to the state of A0 (then take an action on the added and 
> removed items, but thats unrelated to this proposal).
>
> Since each item is unique, once I determine that an item is 
> "still_present" that item no longer needs to be part of the list which we 
> use in determining grouping for the next item.
>
> I coming up with the solution for that task, I came up with Enum.pop_by/2, 
> with the following implementation.
>
> @doc """
> Returns a tuple with the popped value and the remainder of the list. The 
> popped value is found
> by the given function. Once it finds the popped value, it stops searching 
> and returns the result.
>
> Example:
> pop_by([1, 2, 3], fn a -> a == 2 end)
> > {2, [1, 3]}
>
> # No item returns nil and unchanged list
> pop_by([1, 2, 3], fn a -> a == 4 end)
> > {nil, [1, 2, 3]}
> """
> def pop_by(enumerable, fun), do: do_pop_by(enumerable, fun)
>
> defp do_pop_by(enumerable, fun, collector \\ [])
>
> defp do_pop_by([], _fun, collector), do: {nil, Enum.reverse(collector)}
>
> defp do_pop_by([head | tail], fun, collector) do
> if fun.(head) do
> # found item! Reverse collector to maintain original list order and concat 
> to tail
> {head, Enum.reverse(collector) ++ tail}
> else
> do_pop_by(tail, fun, [head | collector])
> end
> end
>
> What do you think? Could also make the collector reversal optional which 
> would improve time complexity in cases where the order of list doesn't need 
> to be maintained
>

-- 
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/45499114-6d84-415b-bc6a-0f1d46e985ad%40googlegroups.com.


Re: [elixir-core:9360] [Proposal] Add Function.const/2

2020-02-04 Thread Ben Wilson
> The code Function.constant(c) is much more expressive and descriptive 
than fn _ -> c end.

To be clear, if this could work without macros, I'd be inclined to agree, 
although I recognize that there may be some who do not. My issue personally 
is that there simply isn't any function you can write that will behave this 
way, for all values of `c`. You could build `constant` as a macro, but I 
think that ends up killing the whole "name a concept" thing, because really 
the dominant concept at hand ends up being how macros work.

On Tuesday, February 4, 2020 at 9:39:48 AM UTC-5, Bruce Tate wrote:
>
> Thanks for the discussion, all. I enjoy being here. 
>
> *Summary: I will bow out of this conversation after this one last attempt. 
> Feel free to skip it. *
>
> I will say that I would use this function frequently in my teaching and in 
> my day-to-day code if I had it. I think it describes a concept that is well 
> known in math, and useful in any functional language. For example, 
> resetting a counter in an agent or genserver with a similar API. Creating a 
> stream of constants as padding/initialization data of arbitrary length 
> (with take later). 
>
> > we'll bloat the language. 
>
> I don't think this is a good argument for foundational concepts. A library 
> that provides names for significant functions in math and programming is 
> important enough.
>
> > I’d argue back that this particular pattern, where you want a list of 
> fixed length with the same value, is much better served by 
> `List.duplicate/2`.
>
> Maybe. But List.duplicate/2 doesn't really solve the same problem. 
> Stream.repeatedly with Function.constant gives me  padding of an arbitrary 
> length, that I can then later instantiate based on the number of columns 
> that I need. It's a great pattern. It's basically fixed vs variable. 
>
> > if I know anonymous functions, I know what’s going on.
>
> Variables, anonymous functions, and the like are not equivalent. A library 
> function has weight and descriptive ability that writing code just doesn't. 
> I can tell you that `fn(x) -> x end` and `Function.identity` are not 
> remotely equivalent when it comes to scanning code. There's a cost to that 
> much syntax. 
>
> I'll say one more thing before moving on from this conversation. 
>
> Naming concepts in code is important. The code Function.constant(c) is 
> much more expressive and descriptive than fn _ -> c end. It gives us a 
> common language across programming languages and theory plus math to 
> express ideas. We in the Elixir community often undersell the idea, and we 
> pay in the idioms that new coders must learn to be successful with our 
> language.
>
> *So thanks to all for a great discussion. I do recognize there's no 
> appetite for these ideas in Elixir, so I'll gracefully bow out. *
>
> -bt
>
>
>
> On Tue, Feb 4, 2020 at 8:58 AM Amos King  > wrote:
>
>> Ben,
>>
>> That is how const is used in Haskell. Although without currying I don’t 
>> see how it is useful. I’m waiting to see an example that drives it home. I 
>> agree with Bruce about naming concepts but I don’t see the concept as 
>> useful in Elixir.
>>
>> Bruce, do you have a code sample using the idea?
>>
>> Amos King
>> CEO
>> Binary Noggin
>>
>> On Feb 4, 2020, at 07:35, Ben Wilson > 
>> wrote:
>>
>> 
>> Addendum: I re-read the proposal because the const/1 vs const/2 thing 
>> confused me, and I'm seeing both in play there. The spec is arity 2, the 
>> example right after though is arity 1, and the Enum example is arity 2 but 
>> without a constant value. The Enum example perhaps makes the most sense, 
>> because you could do:
>>
>> ```
>> Enum.map([1,2,3,4], &const(&1, :foo))
>> ```
>> which would return `[:foo, :foo, :foo, :foo]` effectively replacing the 
>> contents of the list with all `:foo`. Is that the idea?
>>
>> On Tuesday, February 4, 2020 at 8:16:53 AM UTC-5, Ben Wilson wrote:
>>>
>>> I agree with Michal. Additionally, I'm not clear how `const/1` could be 
>>> used in Bruce's example at all.
>>>
>>> To elaborate,  `fn -> foo() end` and `const(foo())` cannot be equivalent 
>>> when `const/1` is merely a function. This becomes readily apparent when 
>>> `foo()` is side effects or side causes. In the first case, `foo()` is never 
>>> evaluated until the wrapping function is called, in the case of `const/1` 
>>> however the function is evaluated and then its return value bound over by a 
>>> function. E

Re: [elixir-core:9357] [Proposal] Add Function.const/2

2020-02-04 Thread Ben Wilson
Addendum: I re-read the proposal because the const/1 vs const/2 thing 
confused me, and I'm seeing both in play there. The spec is arity 2, the 
example right after though is arity 1, and the Enum example is arity 2 but 
without a constant value. The Enum example perhaps makes the most sense, 
because you could do:

```
Enum.map([1,2,3,4], &const(&1, :foo))
```
which would return `[:foo, :foo, :foo, :foo]` effectively replacing the 
contents of the list with all `:foo`. Is that the idea?

On Tuesday, February 4, 2020 at 8:16:53 AM UTC-5, Ben Wilson wrote:
>
> I agree with Michal. Additionally, I'm not clear how `const/1` could be 
> used in Bruce's example at all.
>
> To elaborate,  `fn -> foo() end` and `const(foo())` cannot be equivalent 
> when `const/1` is merely a function. This becomes readily apparent when 
> `foo()` is side effects or side causes. In the first case, `foo()` is never 
> evaluated until the wrapping function is called, in the case of `const/1` 
> however the function is evaluated and then its return value bound over by a 
> function. Eg: `fn -> DateTime.utc_now() end` will always return the current 
> time when evaluated, where as `const(DateTime.utc_now())` will evaluate the 
> current time once and then always return that same time.
>
> That might sound useful, except that we already can do that by simply 
> binding the return value of `DateTime.utc_now()` to a variable and passing 
> that variable around. I'm having difficulty coming up with a scenario 
> where, instead of simply having the value, I have the value wrapped in an 
> anonymous function that I need to call.
>
> Consequently, I struggle to see where `const/1` can actually be used, or 
> how it would work. In the example in the initial proposal, there is this:
>
> ```
> Enum.map([0,1,2,3], &Function.const/2)
> ```
>
> As a minor note, presumably that should be `const/1`, right? More 
> importantly, what is the return value here? If it's `[0, 1, 2, 3]` then 
> `const/1` is equivalent to `identity`. If it's
>
> ```
> [fn -> 1 end, fn -> 2 end, fn -> 3 end, fn -> 4 end]
> ```
>
> then a simple list of integers seems universally more useful.
>
> On Tuesday, February 4, 2020 at 5:03:39 AM UTC-5, Michał Muskała wrote:
>>
>> I’d argue back that this particular pattern, where you want a list of 
>> fixed length with the same value, is much better served by 
>> `List.duplicate/2`.
>>
>>  
>>
>> I think in general, higher order combinator functions like identity, 
>> const, flip, and friends are usually used to facilitate the point-free 
>> style of programming in languages like Haskell. And in general point-free 
>> style usually does not lead to the most readable code. 
>>
>>  
>>
>> Again, referring to the example provided, if I know anonymous functions, 
>> I know what’s going on. When using `Funcion.const`, I have to understand 
>> that concept as well. There’s one extra thing to learn.
>>
>>  
>>
>> Michał.
>>
>>  
>>
>> *From: *"elixir-l...@googlegroups.com"  on 
>> behalf of Bruce Tate 
>> *Reply to: *"elixir-l...@googlegroups.com" 
>> *Date: *Monday, 3 February 2020 at 11:47
>> *To: *"elixir-l...@googlegroups.com" 
>> *Subject: *Re: [elixir-core:9353] [Proposal] Add Function.const/2
>>
>>  
>>
>> My counterpoint is this. Any time you can name a concept that makes it 
>> easier to see what's going on, it's important. 
>>
>>  
>>
>> Examples: 
>>
>> * Create back padding of four blank table cells
>>
>> * use with Stream.repeatedly and take, for example, to initialize a 
>> data structure for OTP. 
>>
>>  
>>
>> I do these two things with pretty good frequency because I build 
>> responsive layouts often needing tabular structure, but without HTML 
>> tables. 
>>
>>  
>>
>> Say you are laying out tables that are responsive but without HTML 
>> tables. You
>>
>> d want to add padding to the end of uneven rows. To create the padding 
>> you'd do 
>>
>>  
>>
>> Stream.repeatedly( fn -> :padding end) |> Enum.take(4)  
>>
>>  
>>
>> where :padding is the constant padding you want. This pattern comes up 
>> with some regularity in my user interfaces. It doesn't hurt anything, and 
>> it would be a great addition to the function module. 
>>
>>  
>>
>> I like this proposal. This is exactly the kind of function you'd expect 
>> to see in the module. 
>>
>>  
>

Re: [elixir-core:9356] [Proposal] Add Function.const/2

2020-02-04 Thread Ben Wilson
I agree with Michal. Additionally, I'm not clear how `const/1` could be 
used in Bruce's example at all.

To elaborate,  `fn -> foo() end` and `const(foo())` cannot be equivalent 
when `const/1` is merely a function. This becomes readily apparent when 
`foo()` is side effects or side causes. In the first case, `foo()` is never 
evaluated until the wrapping function is called, in the case of `const/1` 
however the function is evaluated and then its return value bound over by a 
function. Eg: `fn -> DateTime.utc_now() end` will always return the current 
time when evaluated, where as `const(DateTime.utc_now())` will evaluate the 
current time once and then always return that same time.

That might sound useful, except that we already can do that by simply 
binding the return value of `DateTime.utc_now()` to a variable and passing 
that variable around. I'm having difficulty coming up with a scenario 
where, instead of simply having the value, I have the value wrapped in an 
anonymous function that I need to call.

Consequently, I struggle to see where `const/1` can actually be used, or 
how it would work. In the example in the initial proposal, there is this:

```
Enum.map([0,1,2,3], &Function.const/2)
```

As a minor note, presumably that should be `const/1`, right? More 
importantly, what is the return value here? If it's `[0, 1, 2, 3]` then 
`const/1` is equivalent to `identity`. If it's

```
[fn -> 1 end, fn -> 2 end, fn -> 3 end, fn -> 4 end]
```

then a simple list of integers seems universally more useful.

On Tuesday, February 4, 2020 at 5:03:39 AM UTC-5, Michał Muskała wrote:
>
> I’d argue back that this particular pattern, where you want a list of 
> fixed length with the same value, is much better served by 
> `List.duplicate/2`.
>
>  
>
> I think in general, higher order combinator functions like identity, 
> const, flip, and friends are usually used to facilitate the point-free 
> style of programming in languages like Haskell. And in general point-free 
> style usually does not lead to the most readable code. 
>
>  
>
> Again, referring to the example provided, if I know anonymous functions, I 
> know what’s going on. When using `Funcion.const`, I have to understand that 
> concept as well. There’s one extra thing to learn.
>
>  
>
> Michał.
>
>  
>
> *From: *"elixir-l...@googlegroups.com " <
> elixir-l...@googlegroups.com > on behalf of Bruce Tate <
> br...@grox.io >
> *Reply to: *"elixir-l...@googlegroups.com " <
> elixir-l...@googlegroups.com >
> *Date: *Monday, 3 February 2020 at 11:47
> *To: *"elixir-l...@googlegroups.com " <
> elixir-l...@googlegroups.com >
> *Subject: *Re: [elixir-core:9353] [Proposal] Add Function.const/2
>
>  
>
> My counterpoint is this. Any time you can name a concept that makes it 
> easier to see what's going on, it's important. 
>
>  
>
> Examples: 
>
> * Create back padding of four blank table cells
>
> * use with Stream.repeatedly and take, for example, to initialize a 
> data structure for OTP. 
>
>  
>
> I do these two things with pretty good frequency because I build 
> responsive layouts often needing tabular structure, but without HTML 
> tables. 
>
>  
>
> Say you are laying out tables that are responsive but without HTML tables. 
> You
>
> d want to add padding to the end of uneven rows. To create the padding 
> you'd do 
>
>  
>
> Stream.repeatedly( fn -> :padding end) |> Enum.take(4)  
>
>  
>
> where :padding is the constant padding you want. This pattern comes up 
> with some regularity in my user interfaces. It doesn't hurt anything, and 
> it would be a great addition to the function module. 
>
>  
>
> I like this proposal. This is exactly the kind of function you'd expect to 
> see in the module. 
>
>  
>
> +1 from me. 
>
>  
>
> -bt
>
>  
>
> On Sun, Feb 2, 2020 at 2:42 PM Jesse Claven  > wrote:
>
> That all makes sense! I would say that in Elm it's used somewhat 
> frequently. I don't have access to the previous code that I worked on 
> (changed jobs), so unfortunately I'm unable to grep for `always` to find 
> some good examples.
>
>  
>
> In the codebase at my new job, there's a couple of places where `fn _ -> 
> something` is (my original example in this thread). It's basically for 
> anywhere you'd want to ignore some value, and always return something else. 
> I tried searching through GitHub for that code sample but the search 
> functionality was a little subpar.
>
>  
>
> I understand about keeping the stdlib small, but for a relatively small 
> function, and one that's considered "table stakes" in most FP languages, 
> perhaps it would be a good fit?
>
>
> On Thursday, 30 January 2020 11:20:58 UTC, Wiebe-Marten Wijnja wrote: 
>
> The reason `Function.identity/1` was added after it was requested many 
> times previously, was that at some point everyone agreed that it would 
> improve Elixir's documentation, because it is easier to search for than 
> `&(&1)`.
>
> The `const` pattern is much less wide-spread. In e.g. Haskell it sees some 
>

Re: [elixir-core:9221] Re: Automatically time long-running iex commands.

2019-10-17 Thread Ben Wilson
I really like this feature idea. Often you don't know or expect that a 
particular function will take so long, and it's precisely at that point 
that you go "man, I wish I had timed that". Particularly if the function is 
doing a side effect, it may be non trivial to try again.

Perhaps if the messaging all happened with the `iex()` prefix it might make 
more sense where it's coming from?

iex(1)> some_long_fun()
iex(taking more than 5 seconds ...)
iex(returned after 15 seconds)
{:ok, :foo}
iex(2)>

On Thursday, October 17, 2019 at 8:20:16 PM UTC-4, José Valim wrote:
>
> Showing the time every time (and other metadata) would definitely be too 
> verbose, even inside the prompt. But I understand the origin of the message 
> being unclear.
> -- 
>
>
> *José Valim*
> www.plataformatec.com.br
> Skype: jv.ptec
> Founder and Director of R&D
>

-- 
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/83381825-2c8d-4d47-b69f-852721b933ba%40googlegroups.com.


[elixir-core:9146] Re: [Proposal] latest and earliest functions for DateTime and NaiveDateTime

2019-10-10 Thread Ben Wilson
FWIW We have an earliest_date and latest_date helper in almost every Elixir 
app we've built. The Enum.sort solution requires requires too many leaps to 
be at a glance readable if it's been a bit since you used DateTime.compare.

Definitely a fan of including this.

On Thursday, October 10, 2019 at 5:31:29 AM UTC-4, Wiebe-Marten Wijnja 
wrote:
>
> Playing devil's advocate here for a minute: The wanted functionality could 
> also be reached using
>
> Enum.sort(enumerable, &(DateTime.compare(&1, &2) in [:lt, :eq]))
>
> for `DateTime.earliest`
>
> and similarly:
>
> Enum.sort(enumerable, &(DateTime.compare(&1, &2) in [:eq, :gt]))
>
> for `DateTime.latest`.
>
> Arguably this does require some mental gymnastics. However, is that enough 
> reason to introduce eight new functions? (two for each of Time, Date, 
> NaiveDateTime and DateTime)?
>
> Maybe these mental gymnastics are not 'too bad'?
> Or maybe we do want to make it somewhat easier for the users, but there 
> exists a simpler, more fundamental alternative we could implement, which 
> could then be re-usable in multiple contexts?
>
> For instance, if we only had `DateTime.earliest(dt1, dt2)` then we could 
> write:
>
> Enum.sort(enumerable, &(DateTime.earliest(&1, &2) == &1))
> for the first case, and 
> Enum.sort(enumerable, &(DateTime.earliest(&1, &2) == &2))
> for the second.
>
> ~Qqwy/Marten
>

-- 
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/bd408b05-f8f5-4ebe-b466-f5af2cbd66d9%40googlegroups.com.


[elixir-core:9114] Re: Suggestion Add Rubys tally

2019-09-30 Thread Ben Wilson
This function is really good as an exercise for new programmers to 
implement, for sure. In terms of regular workflows, how often does this 
exact function really come up? Given that it's only three lines to 
implement, I'm not sure that adding it to the standard library contributes 
much towards solving people's problems.

On Monday, September 30, 2019 at 11:16:17 AM UTC-4, Osawa QWYNG wrote:
>
> Hi! Thank you for a great programing language.
> This is a suggestion for a new enum function.
>
>
> Add tally function like Rubys tally.
>
>
> tally is Rubys 2.7.0 new function
>
> https://bugs.ruby-lang.org/issues/11076
>
> and this is My PR for Elixir
>
> https://github.com/elixir-lang/elixir/pull/9373
>
>
> iex> Enum.tally(~w{ant buffalo ant ant buffalo dingo})
> %{"ant" => 3, "buffalo" => 2, "dingo" => 1}
>
> iex> Enum.tally(~w{aa aA bb cc}, fn x -> String.downcase(x) end)
> %{"aa" => 2, "bb" => 1, "cc" => 1}
>
>
> The following article is more about this.
>
> https://medium.com/@baweaver/ruby-2-7-enumerable-tally-a706a5fb11ea
>
>
> Ruby 2.7.0 has not released yet but this function is really good
>

-- 
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/01590355-9eee-4de8-bcd2-18e4815fc615%40googlegroups.com.


Re: [elixir-core:8995] [Proposal] identity function

2019-07-30 Thread Ben Wilson
I think having Enum.filter(list, &Function.identity/1) actually reads 
pretty well. It avoids the issue with putting it in Kernel, and provides a 
very explicit name which speaks to Bruce's goal of naming concepts.

On Tuesday, July 30, 2019 at 12:47:08 PM UTC-4, Allen Madsen wrote:
>
> I don't have a strong opinion on this function's inclusion. It's not 
> mandatory that it live in Kernel though. It could exist on Function.
>
> Allen Madsen
> http://www.allenmadsen.com
>
>
> On Tue, Jul 30, 2019 at 12:29 PM Chris McCord  > wrote:
>
>> I’m just catching up on this thread now, but I’m in the “not valuable 
>> enough to be added” camp. I’ve personally never needed such an abstraction 
>> – on my own or while teaching. Also, an anon function serves the purpose 
>> when needed without introducing a new concept. From the beginner 
>> perspective, I think `identify` adds more noise where it isn’t needed. Even 
>> following this thread and reading other lang usage, I still find the name 
>> awkward and struggle to see it being a net benefit to my code vs what I’d 
>> happily write today. Given how trivial it is to return the value yourself 
>> in a concise and clear way, I don’t think the value of it squatting in 
>> kernel is enough to justify an addition to the std lib. 
>>
>> On Jul 21, 2019, at 8:47 AM, Bruce Tate > 
>> wrote:
>>
>> I want to speak to the beginners argument.  I am not guessing. I spend 
>> 6-8 hours teaching and mentoring every week, and it's more when school is 
>> in. Concepts are easier to teach when those concepts have names and big 
>> concepts can be broken down into smaller ones. The students I teach are 
>> about 80% new to FP and about 40% new to programming in general. 
>>
>> I will take the advice of mixing in FP.identity if it cuts against the 
>> grain of what Elixir is about. 
>>
>> Thanks to all for making Elixir the best it can be... let's keep it 
>> civil. I think it makes a lot of sense to take José's suggestion and 
>> collect some of these concepts into a library and prove their worth there, 
>> to language learners and otherwise. 
>>
>> -bt
>>
>> On Mon, Jul 15, 2019 at 5:12 AM Andrea Leopardi > > wrote:
>>
>>> My 2 cents. To me a strong argument against this is that &identity/1 
>>> still looks confusing to newcomers with the capture syntax (how many "why 
>>> can't I just write identity like in Js questions do we get after all), so 
>>> summed with the other arguments against it makes me not want to add this to 
>>> the language personally.
>>>
>>> On Mon, 15 Jul 2019 at 09:30, Masoud Ghorbani >> > wrote:
>>>
 Isn't possible to have something like JavaScript arguments which 
 correspond with a list of parameters passed to function? 
 its more handy to lookup a parameter in a list or map until working 
 with a function to get a given parameter.

 On Tuesday, July 2, 2019 at 11:10:45 PM UTC+4:30, José Valim wrote:
>
> Thanks Chris, it is important that someone being counter arguments, 
> even if they can be disproved. :)
>
> I definitely see how such a small function can be useful but, at the 
> same time, I am not convinced about the name "identity".
>
> I found it curious that Clojure actually have an identity function 
> because the definition of Identity they use when talking about values and 
> change is a more complex one (and one that really stuck with me):
>
> *> By identity I mean a stable logical entity associated with a series 
> of different values over time*
>
> https://clojure.org/about/state#_working_models_and_identity
>
> Of course, my interpretation above is likely uncommon and there are 
> other interpretations of identity that would fit nicely.
>
> Anyway, to move the discussion forward, can someone do a more complete 
> survey on what this function are called in many of the other languages? I 
> just want to make sure we do our due diligence before adding it to the 
> language.
>
> Thank you,
>
> *José Valim*
> www.plataformatec.com.br
> Skype: jv.ptec
> Founder and Director of R&D
>
>
> On Tue, Jul 2, 2019 at 8:25 PM Christopher Keele  
> wrote:
>
>> Derp, I knew that. Good point.
>>
>> On Tue, Jul 2, 2019 at 9:55 AM Michał Muskała  
>> wrote:
>>
>>> Because Elixir is a lisp-2 language, variables and functions are in 
>>> different "namespaces". This means you can have local variables with 
>>> names 
>>> of local functions without any issues, but it also means you need 
>>> different 
>>> syntax when you want to call a function contained in a variable. Or 
>>> formulated differently - variables can't shadow functions. For example, 
>>> consider: 
>>>
>>> bar = &foo/0
>>> bar.() #=> 1
>>> bar() #=> 2
>>> def foo(), do: 1def bar(), do: 2
>>>
>>> Having a Kernel.id/1 function would not preclude you from using 
>

[elixir-core:8987] Re: [Proposal] Map.put_new!

2019-07-25 Thread Ben Wilson
The presence of rarely used functions is not an argument for the addition 
of further rarely used functions.

On Wednesday, July 24, 2019 at 1:05:59 PM UTC-4, Mário Guimarães wrote:
>
> It seems this function was proposed here 
> https://github.com/elixir-lang/elixir/pull/5917
>
> and dropped because:
>
>
>1. put_new and put_new! pair behaves differently from !-paired 
>functions, I’m not sure if it’s good thing to break expectations in that 
>case.
>2. I don’t feel a huge need for put_new! - put_new itself is already 
>rather rare use case, this one would be even rarer.
>
> Regarding point 1) I can say that Map.replace!/update! also " behaves 
> differently from !-paired functions", yet they still exist
>
> Regarding point 2) well ... there many other functions many of us found 
> very infrequent or no use so far ¯\_(ツ)_/¯
>
> My opinion is that it can be useful to make the code more bulletproof, 
> much like Map.replace!/update! do.
>
> Mário
>
>
>
>
> quarta-feira, 24 de Julho de 2019 às 17:47:34 UTC+1, Mário Guimarães 
> escreveu:
>>
>> Hello,
>>
>> presently there is no function that throws an error in case we want to 
>> put a really new key in a map.
>>
>> The function Map.put_new only does nothing if the key is already there.
>>
>> The idea for Map.put_new! is to throw an error if the key is there. The 
>> use case is the developer who wants to be sure that the key is not there, 
>> as otherwise it means there is an error in the application code. As such, 
>> an exception should be raised.
>>
>> Is this a useful addition to Map?
>>
>> Thanks
>> Mário
>>
>

-- 
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/0aa70608-1464-4c61-acb3-b38c1a6c4633%40googlegroups.com.


[elixir-core:8563] Re: Enum.repeat/2

2019-03-29 Thread Ben Wilson
You can sort of do this with `Stream.repeatedly(fn -> :something end) |> 
Enum.take(5)`. It's a little longer, although it reads rather nicely.

On Friday, March 29, 2019 at 7:48:54 AM UTC-4, Hylke Alons wrote:
>
> Hah, this is great! thanks!
>
> On Friday, 29 March 2019 12:47:14 UTC+1, Wojtek Mach wrote:
>>
>> iex(1)> List.duplicate(:something, 5)
>> [:something, :something, :something, :something, :something]
>>
>> :-)
>>
>> Hi there,
>>>
>>> I would like to know your opinion about an `Enum.repeat/2` function. In 
>>> test, I notice often that I write:
>>>
>>> Enum.map(1..5, fn(_) ->  :something end) 
>>> [:something, :something, :something, :something, :something]
>>>
>>> or 
>>>
>>> for (_ Enter code here... <- 1..5), do: :something
>>> => [:something, :something, :something, :something, :something]
>>>
>>> As I am not interested in the value of the input, I think a 
>>> `Enum.repeat/2` function would be more efficient:
>>> Enum.repeat(5, fn -> :something end)
>>> => [:something, :something, :something, :something, :something]
>>>
>>>
>>> I am aware that `Enum.times/2` is deprecated in the past in favour of 
>>> ranges. I want to highlight that in that function, the value was passed to 
>>> the function.
>>>
>>>
>>> What is your take? Or perhaps I overlooked a function?
>>>
>>

-- 
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/aee223df-0161-4c16-96e2-eb936c18d456%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:8560] Re: [proposal] Tree-Sitter grammar parser for Elixir

2019-03-29 Thread Ben Wilson
Can you elaborate for those of us with less context? What is tree-sitter? 
What are you proposing?

On Thursday, March 28, 2019 at 10:10:14 PM UTC-4, João Paulo Silva de Souza 
wrote:
>
> Seems like I wrongly opened an issue instead of posting here first -> 
> https://github.com/elixir-lang/elixir/issues/8917.
>
> My reasoning is that this is not a language feature and thus I thought I 
> could skip the proposal process. My apologies.
>
>
> 
>
> https://tree-sitter.github.io/tree-sitter/#available-parsers
>
> It seems like Elixir is not in the roadmap for language support.
>
> Atom has the most complete implementation currently. I expect other 
> editors (e.g. Vim, VSCode, Emacs, etc...) to follow in adoption when the 
> API stabilizes and more bugs are fixed.
>
> Project: https://github.com/tree-sitter/tree-sitter
> Neovim: https://github.com/neovim/neovim/pull/9219
> Emacs: https://github.com/karlotness/tree-sitter.el
> VSCode: https://github.com/Microsoft/vscode/issues/50140
>
> Example grammar for Javascript - 
> https://github.com/tree-sitter/tree-sitter-javascript/blob/master/grammar.js
>

-- 
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/249271ec-175c-4fbc-a087-7c73381aa496%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elixir-core:8478] Re: [Proposal] Add invert() method to Map module

2019-02-10 Thread Ben Wilson
lowing would raise an error:
> Map.invert!(%{a: 1, b: 1})
> )
>
> In contrast, the Map.invert/1 method would allow for non-unique values. 
> It would return a map where the values are a list of keys in the original 
> map. 
>
> (i.e. 
>
> Map.invert(%{"banana" => "yellow", "strawberry" => "red", "cherry" => 
> "red"}) 
>
> would return 
>
> %{"yellow" => ["banana"], "red" => ["strawberry", "cherry"]}.   
> ).
>
> This idea is from solutions found in other languages (i.e. "Perl Cookbook 
> <https://nnc3.com/mags/Perl3/cookbook/ch05_09.htm>", "Ruby Cookbook 2nd ed 
> <https://books.google.ca/books?id=E_KMa5Zab0MC&pg=PA178&lpg=PA178&dq=ruby+cookbook+invert+hash&source=bl&ots=eB8M4nqBTf&sig=ACfU3U3w_4pSzBUDTTvXQ6gpFLY-lifhnw&hl=en&sa=X&ved=2ahUKEwiEoqfn2LDgAhUkITQIHXVUDVcQ6AEwBXoECAkQAQ#v=onepage&q=ruby%20cookbook%20invert%20hash&f=false>",
>  
> or see here 
> <https://stackoverflow.com/questions/7304980/invert-keys-and-values-of-the-original-dictionary>
>  
> or here 
> <https://www.coursera.org/lecture/learn-to-program/inverting-a-dictionary-QIj4i>
>  
> for Python).  This way no data is lost through the inversion.  Ideally, 
> if possible, we can use a property-based test to validate that inverting 
> the map 2 times will always returns the initial map.
>
> What are your thoughts?
>
> Thanks,
>
> Justin
>
>
> On Thursday, February 7, 2019 at 5:45:49 AM UTC-7, Andrea Leopardi wrote:
>>
>> A big problem is also that semantically keys and values are very 
>> different in maps, in that keys are unique and values aren't. Inverting a 
>> map could cause problems if you don't take that into account. Of course, if 
>> you use the Map.new/2 solution the problem is there anyways, but at least 
>> you're being explicit in what happens.
>>
>> Only one use case has been presented and I think I would need at the very 
>> least a few more before considering whether this belongs in core. When a 
>> function is this small and the use cases are rare and specific, I think 
>> implementing it in your own code usually works best.
>>
>> On Wed, 6 Feb 2019 at 23:36, Ben Wilson  wrote:
>>
>>> Map.invert is at least largely harmless, unlike some of the other 
>>> proposals that happen. It's still a little odd to me to have a function 
>>> that boils down to just:
>>>
>>> Map.new(map, fn {k, v} -> {v, k} end)
>>>
>>> Honestly that is almost clearer if you've never heard the word "invert" 
>>> with respect to maps.
>>>
>>> On Wednesday, February 6, 2019 at 1:35:49 AM UTC-5, Justin Gamble wrote:
>>>>
>>>> Hi,
>>>>
>>>> I think an invert() method on Map would be convenient to use.  It is 
>>>> only a handful of lines of code to add to a custom program, but why should 
>>>> users need to do that?  In my opinion this basic functionality should be 
>>>> implemented by the Map module. 
>>>>
>>>> The invert() method would operate the same way it does for Ruby:
>>>> https://ruby-doc.org/core-2.2.2/Hash.html#method-i-invert
>>>>
>>>> Recently I wanted to invert a map in one of my Elixir programs (details 
>>>> below), and I googled and found the below solution by Chris McCord in h
>>>> ttps://stackoverflow.com/questions/26614682/how-to-change-all-the-values-in-an-elixir-map
>>>> :
>>>>
>>>> def invert(map) when is_map(map) do
>>>> for {k, v} <- map, into: %{}, do: {v, k}
>>>>   end
>>>>
>>>> I would basically like the above function to be added to the Elixir.Map 
>>>> module.
>>>>
>>>> Here is the scenario for which I wanted to use this the invert function:
>>>>
>>>> *My Elixir program is synchronizing Robot Framework source code files 
>>>> with TestRail.  Robot Framework defines automated test cases.  TestRail is 
>>>> a web-based Test Case Management system.   The goal is to synchronize 
>>>> TestRail to contain all the tests that are defined in the Robot Framework 
>>>> files, and in the same directory structure.*
>>>>
>>>> *Originally the Elixir program was specified to only create test cases 
>>>> in TestRail.  When you are creating a test case, the TestRail API 
>>>> <http://docs.gurock.com/testrai

[elixir-core:8471] Re: [Proposal] Add invert() method to Map module

2019-02-06 Thread Ben Wilson
Map.invert is at least largely harmless, unlike some of the other proposals 
that happen. It's still a little odd to me to have a function that boils 
down to just:

Map.new(map, fn {k, v} -> {v, k} end)

Honestly that is almost clearer if you've never heard the word "invert" 
with respect to maps.

On Wednesday, February 6, 2019 at 1:35:49 AM UTC-5, Justin Gamble wrote:
>
> Hi,
>
> I think an invert() method on Map would be convenient to use.  It is only 
> a handful of lines of code to add to a custom program, but why should users 
> need to do that?  In my opinion this basic functionality should be 
> implemented by the Map module. 
>
> The invert() method would operate the same way it does for Ruby:
> https://ruby-doc.org/core-2.2.2/Hash.html#method-i-invert
>
> Recently I wanted to invert a map in one of my Elixir programs (details 
> below), and I googled and found the below solution by Chris McCord in h
> ttps://stackoverflow.com/questions/26614682/how-to-change-all-the-values-in-an-elixir-map
> :
>
> def invert(map) when is_map(map) do
> for {k, v} <- map, into: %{}, do: {v, k}
>   end
>
> I would basically like the above function to be added to the Elixir.Map 
> module.
>
> Here is the scenario for which I wanted to use this the invert function:
>
> *My Elixir program is synchronizing Robot Framework source code files with 
> TestRail.  Robot Framework defines automated test cases.  TestRail is a 
> web-based Test Case Management system.   The goal is to synchronize 
> TestRail to contain all the tests that are defined in the Robot Framework 
> files, and in the same directory structure.*
>
> *Originally the Elixir program was specified to only create test cases in 
> TestRail.  When you are creating a test case, the TestRail API 
>  requires 
> you to specify the ID of the directory (aka "section") where the case is 
> written.  For this I use an Elixir Map to map paths to section IDs.  When I 
> want to create a file in directory "/path/to/test.robot", then I Lookup the 
> section ID from my map & then call the "add_case" TestRail API function.*
>
> *That version of the program was a success.  My boss was impressed and 
> next asked for enhancements to the program.  The new functionality being 
> requested is to have existing TestRail Test Cases get updated with the 
> latest test steps defined in Robot Framework.  Part of that update is to 
> verify that the path to the test case is the same in the Robot Framework 
> source code and in the TestRail.  In this case we first call the TestRail 
> API to lookup a test case, at which point we know the section ID that it 
> belongs to.  But we need to translate that to a directory path and confirm 
> that this path is the same location as where the test file exists in the 
> Robot Framework source code.  *
>
> *For updating, it makes sense to also be able to use an Elixir Map to map 
> from the Section ID back to the Path -- the inverse of the original map.  *
>
> *It is true that I could iterate through the original map until I found 
> the section ID in the value section, and then return the map index.  But 
> that seems awfully inefficient when you consider that there are hundreds of 
> test files and thousands of tests.  So I decided an inverse map would 
> provide faster lookup, at the cost of more memory being used.  Also note 
> that in my scenario both the indexes and the values are unique; it is a 
> 1-to-1 mapping.*
>
>
> This is just one example scenario.  I imagine other examples exist, or 
> else the invert() function would never have been created in the Ruby 
> community.
>
>

-- 
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/745bf765-c4b8-494e-9ded-7d1a50c05c5e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:8385] Re: Enum.sum/2

2018-12-02 Thread Ben Wilson
I don't really agree that it makes the intent clearer. It combines two 
distinct and unrelated activities. One takes the sum of a list, the other 
maps each value in a list to some other value. list |> Enum.map(& &1 * 2) 
|> Enum.sum expresses this perfectly. If you're going for lolspeed and need 
to avoid the second pass then you want a bare recursive function anyway and 
shouldn't even use Enum.

On Saturday, December 1, 2018 at 11:18:58 AM UTC-5, Sean Handley wrote:
>
> Hello,
>
> I'd like to propose *Enum.sum/2*, where the second argument is a function.
>
> This will allow writing
>
> Enum.sum([1, 2, 3], &(&1 * 2))
>
> instead of
>   
> Enum.map([1,2,3], &(&1 * 2)) |> Enum.sum()
>
> The advantages are:
>
> - Write less code.
> - One few iteration across the collection.
>
> I have a branch prepared - 
> https://github.com/elixir-lang/elixir/compare/master...seanhandley:map_with_func
>
> Please let me know your thoughts.
>
> Cheers,
> Sean
>
>

-- 
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/fb7ab97c-3b0d-4772-9525-617cc765414a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:7936] Re: [Proposal] Add a pipe-right macro |>> to Kernel

2018-03-09 Thread Ben Wilson
I would highly recommend taking a walk through existing threads in the 
mailing list and forums. This and other similar pipe additions have been 
requested before. I'm glad you're interested in improving the language, but 
the proposal itself doesn't reflect a familiarity with existing answers to 
this very question.

On Friday, March 9, 2018 at 2:45:24 PM UTC-5, Boyd Multerer wrote:
>
> A pattern I find myself in all the time is when I am writing a piped 
>  series of function calls, when I need to pass the result into some 
> parameter other than the first one.
>
> Something like this.
>
> Map.get( p_map, puid )
> |> Group.insert_at( index, uid )
> |> ( &Map.put(p_map, puid, &1) ).()
> |> ( &put_primitive_map(graph, &1) ).()
> |> something_else()
>
> The trick to pipe into a anonymous function works, but is ugly and least 
> to poor readability.
>
> I would really like a pipe_right macro, which would work something like 
> this.
>
> Map.get( p_map, puid )
> |> Group.insert_at( index, uid )
> |>> Map.put(p_map, puid, &1)
> |>> put_primitive_map(graph, &1)
> |> something_else()
>
> Note that it should be interchangeable with the standard pipe without 
> breaking the piping flow.
>
> I keep running into this and reached the point where I really want this 
> macro in the Kernel module.
>
>

-- 
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/2bc5ebe8-eeba-4834-a155-e342578e8330%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:7922] Re: [Proposal] Create maybe(t) typespec

2018-02-28 Thread Ben Wilson
Is nillable(String.t) less boilerplate than String.t | nil ?

On Wednesday, February 28, 2018 at 9:12:42 AM UTC-5, Yordis Prieto wrote:
>
> I am more interested on the solution of `nil | t` I dont mind changing the 
> name to `nillable(t)` or whichever other word in English.
>
> The needs come from Ecto schemas and most of the struct fields will be 
> nillable(t), I thought it would be good to have something that represent 
> that common use case.
>
> On Tuesday, February 27, 2018 at 4:11:39 AM UTC-8, Yordis Prieto wrote:
>>
>> Introducing `maybe(t)` it will reduce the boilerplate code for `nil | 
>> something` 
>>
>> It is more convenience to write it this way, at least for me.
>>
>> What are your thoughts about it?  
>>
>

-- 
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/c0d589bc-951d-4b5d-afef-d652d8a84310%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:7919] Re: [Proposal] Create maybe(t) typespec

2018-02-27 Thread Ben Wilson
maybe(t) is traditionally `Some(t) | None`, which isn't really the same as 
`nil | t`. The closest analogue would seem to me to be `{:ok, t} | :error` 
although that doesn't quite communicate the same thing.

On Tuesday, February 27, 2018 at 7:11:39 AM UTC-5, Yordis Prieto wrote:
>
> Introducing `maybe(t)` it will reduce the boilerplate code for `nil | 
> something` 
>
> It is more convenience to write it this way, at least for me.
>
> What are your thoughts about it?  
>

-- 
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/3b39e876-4286-4602-955a-de513d4dfc27%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:7907] Re: [Proposal] Kernel.is_module?/1

2018-02-25 Thread Ben Wilson
Can you elaborate on motivating code patterns? Every instance where I've 
wanted to determine if a specific module is around has been a compile time 
question for meta-programming purposes, and the `Code.ensure_loaded?` 
function has worked great for that.

On Sunday, February 25, 2018 at 6:56:25 PM UTC-5, t...@scalpel.com wrote:
>
> I've found that in practice both `Code.ensure_loaded` and 
> `Code.ensure_compiled?` are both extremely slow in practice. Also it is not 
> very intuitive that this is what you should be reaching for when attempting 
> to check what type something is. The standard pattern that has been 
> established is the "is_*" in the Kernel. I think we should continue that 
> pattern with modules as well.
>

-- 
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/7e022ca7-4129-47bd-b618-121bde6cf176%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elixir-core:7885] Introduce Sum Types

2018-02-16 Thread Ben Wilson
Can you elaborate on the safety provided by doing `%Struct{} = ` on a 
function? There are no compile time checks that calls to that function are 
actually of that struct type, just runtime checks on the data. Put another 
way this isn't really a type check, but an assertion.

On Friday, February 16, 2018 at 6:38:07 AM UTC-5, maen...@joshmartin.ch 
wrote:
>
> Hey Louis,
>
> I think it should include compile time checks. Mostly I would expect those 
> for function headers, case blocks and with blocks.
>
> Dialyzer already checks many of those conditions, but I would like to go a 
> step further.
> Your mentioned library looks really interesting. Making it work together 
> with existing type specifications would be really cool.
>
> With for example structs, I can achieve safety really easy by adding 
> *%Struct{} 
> = my_input* to the function header.
>
> I would like to have a mechanism that works similarly, but additionally 
> checks uncovered types of a sum. (If you would for example not cover the 
> None of a Maybe)
>
> I think that this could tremendously improve the code quality.
>
> Cheers,
> Jony
>
> Am Freitag, 16. Februar 2018 11:57:00 UTC+1 schrieb Louis Pilfold:
>>
>> Hey Jony
>>
>> Would this involve some form of compile time type checking for these 
>> values? If not we already have them in the form of tuples.
>>
>> @type result :: {:ok, string()} | {:error, string()}
>>
>> If you want compile time checks this would be more difficult. I've 
>> experimented a little with compile time checks with macros, check it out 
>> here -> https://github.com/lpil/sum
>>
>> Cheers,
>> Louis
>>
>> On Fri, 16 Feb 2018 at 10:33  wrote:
>>
>>> Hi all,
>>>
>>> First I want to thank you all for your great work on the elixir language!
>>>
>>> Have there been some thoughts to introduce Tagged Unions into elixir?
>>> I would really love to use sum types like Either or simple enums in my 
>>> daily work and have some support of the language in handling them.
>>>
>>> What do you think about this?
>>>
>>> Cheers,
>>> Jony
>>>
>>> -- 
>>> 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/4052d8d9-6eda-46c9-b259-fb0f2e041120%40googlegroups.com
>>>  
>>> 
>>> .
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>

-- 
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/f72949db-50aa-433e-abb9-f5c1ba518008%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:7877] Re: Proposal: Option to omit comments from generated mix projects

2018-02-15 Thread Ben Wilson
I too would find this useful.

On Wednesday, February 14, 2018 at 2:19:04 PM UTC-5, pragdave wrote:
>
> ✓👍
>
> On Thursday, January 18, 2018 at 9:09:32 AM UTC-6, Ville Hellman wrote:
>>
>> Hey all,
>>
>> I'm proposing a new option for the `mix new` task: `--nocomments` when 
>> run with this option it would omit all comments from the generated project 
>> files.
>>
>> When first starting with Elixir I found the comments in the files very 
>> useful indeed but more recently I've found them to be mostly a nuisance 
>> that I end up deleting straight away. This is particularly bad in the 
>> config file (of which most is comments) or in a Phoenix project. If this 
>> proposal is implemented I'm planning on opening similar proposal for the 
>> Phoenix project.
>>
>> I would like to put together a pull request for this if the community 
>> agrees it would be a valuable addition.
>>
>> I have had a preliminary look at the `Mix.Tasks.New` module and the work 
>> involved and would like to discuss couple of different approaches to how 
>> this could be implemented.
>>
>> Thanks,
>> Ville
>>
>> ps. congratulations to everyone involved in getting 1.6 released!
>>
>

-- 
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/a88a8473-9729-4832-8ba0-7f1eb5580173%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:7829] Re: [Proposal] Add GenServer.query and GenServer.handle_query

2018-01-30 Thread Ben Wilson
Have you evaluated an Agent for your purposes? It has basically exactly 
this function.

On Tuesday, January 30, 2018 at 9:17:08 AM UTC-5, Federico Bergero wrote:
>
> Hi all, 
>  I'm proposing a new GenServer callback `query` similar to the 
> call but which does not change the process state.
> I find myself writing a lot of `handle_call` callbacks like
>
> def handle_call(request, _from, state) do
>   ...
>   ...
>   {:reply, result, state}
> end
>
>
>
>
> with the `handle_query` this could be written as 
>
> def handle_query(request, _from, state) do
>   ...
>   ...
>   {:reply, result}
> end
>
>
> This is easier to read and write. 
>
> A common use case is when you need some computation that depends on the 
> GenServer state. Another is when the GenServer has a side effect and the 
> calls to the server does not changes the actual process state but an 
> external component.
>
>
> Together with the callback a new GenServer.query function should be 
> implemented which calls the callback on the server context. 
>
> I'm not familiar with the internals of the compiler/GenServer but this 
> could also bring optimization opportunities.
>

-- 
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/249e8c65-c2a2-4cbc-9956-1868d68b022f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elixir-core:7826] Proposal: allow newline after `with`

2018-01-30 Thread Ben Wilson
This is achievable with `\` btw:

with \
  %{x: x} <- y
do
  x
end

On Tuesday, January 30, 2018 at 7:39:07 AM UTC-5, Po Chen wrote:
>
> Ah I thought `with` was part of the language, then I realized how small 
> the language core is.
> Now I wish the language is actually a little bigger :S mixed feelings.
>
> Thanks for the reply!
>
> On Tuesday, 30 January 2018 23:20:49 UTC+11, José Valim wrote:
>>
>> Imagine you have this code:
>>
>>foo = 1
>>bar = 2
>>foo bar do
>>  :ok
>>end
>>
>> Would you expect it to be equivalent to:
>>
>>foo = 1
>>bar = 2
>>foo
>>bar do
>>  :ok
>>end
>>
>> It isn’t because “foo” in its own line is a valid expression. Replace 
>> “foo” by “with” and you can see why your proposed syntax doesn’t work.
>>
>> If you want to write it as you proposed, you need to use parens:
>>
>>foo = 1
>>bar = 2
>>foo(
>>  bar
>>) do
>>  :ok
>>end
>> -- 
>>
>>
>> *José Valimwww.plataformatec.com.br 
>> Founder and Director of R&D*
>>
>

-- 
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/a644c670-f090-4eaf-a0df-fa47333519b8%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elixir-core:7797] Re: [Proposal] Add async functions definitions

2018-01-23 Thread Ben Wilson
An important thing to note is that in Elixir it's generally the caller of a 
function that determines whether they  want sync or async behaviour, not 
the callee. Generally speaking you simply write functions that take input 
and return output. If a given caller of that function wants that to happen 
async then it can use Task or some other construct for doing so. If another 
caller wants to do it sync then they just call the function.

Throughout all of this though all the processes are async with respect to 
one another already, and this is enforced by the VM and requires no special 
language handling.

On Tuesday, January 23, 2018 at 2:54:03 PM UTC-5, Pedro Medeiros wrote:
>
> Thanks for the response people.
>
> I knwon using tasks always is not the best way to go, but I do fell we can 
> make somehow a better abstraction for processes only with what the language 
> have.
>
> I’m gonna write something down later, thanks for the advice Wojtek.
>
> On Tue, Jan 23, 2018 at 2:38 PM Wojtek Mach  > wrote:
>
>> > Also another benefit is having a syntax more similar to other 
>> languages. This can make Elixir more welcoming for people from other 
>> communities such as python or javascript.
>>
>> Adding syntax and APIs that feel familiar is one way to potentially make 
>> it easy for people to learn Elixir. It doesn't seem like a scalable 
>> approach however because it'd likely result in bloat of the language and/or 
>> stdlib.
>>
>> Another way is to prepare learning materials, perhaps a blog post 
>> "Python/JavaScript async in Elixir", where functions like Task.async,await, 
>> Task.Supervisor.async_nolink, Task.async_stream and spawn are discussed.
>> One could even show that with macros we can implement "async" keyword 
>> pretty easily:
>>
>> defmodule DefAsync do
>>   defmacro defasync(call, do: block) do
>> quote do
>>   def unquote(call) do
>> Task.async(fn -> unquote(block) end)
>>   end
>> end
>>   end
>> end
>>
>>
>> defmodule Foo do
>>   import DefAsync
>>
>>   defasync delayed_foo(value) do
>> :timer.sleep(1_000)
>> IO.inspect value
>>   end
>> end
>>
>>
>> Foo.delayed_foo(42) |> Task.await()
>>
>> W dniu wtorek, 23 stycznia 2018 16:01:06 UTC+1 użytkownik Pedro Medeiros 
>> napisał:
>>
>>> Hi,
>>>
>>> I'm writing this proposal based on what I've been doing with 
>>> Python/Javascript. A way ppl on those communities are doing asynchronous 
>>> call nowadays is by declaring an async function and if there is a need to 
>>> wait for its result calls the function await. Once we have the module Task 
>>> that is capable of handling mostly user cases about async/await feature on 
>>> those languages. I think we can add async to the function definition to 
>>> implement 
>>>
>>> defmodule Foo do
>>>   async def bar(x)# code
>>>   endend
>>>
>>>
>>>
>>> And on the code by calling Foo.bar/1 we return a Task. And by calling 
>>> Task.async Foo.foo(1) the result can be returned.
>>>
>>> the main benefits on having an approach like that is basically code 
>>> readability when it is necessary to run a single function as a separate 
>>> process. today that can be done with something like that
>>>
>>> task = Task.async(fn ->
>>>   Foo.bar(:arg)end)Task.await(task)
>>>
>>>
>>> or
>>>
>>> task = Task.async(Foo, :bar, [:arg])Task.await(task)
>>>
>>>
>>> Also another benefit is having a syntax more similar to other languages. 
>>> This can make Elixir more welcoming for people from other communities such 
>>> as python or javascript.
>>> -- 
>>>
>> Pedro Medeiros
>>> --
>>> Cel: +55 (21) 9914-86898
>>>
>> Email: pedr...@gmail.com
>>>
>>
>>> Beautiful is better than ugly,
>>> Explicit is better than implicit,
>>> Simple is better than complex,
>>> Complex is better than complicated.
>>>
>>> The Zen of Python, by Tim Peters
>>>
>> -- 
>> 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/749338f8-ab6b-4849-a440-052a96686e95%40googlegroups.com
>>  
>> 
>> .
>> For more options, visit https://groups.google.com/d/optout.
>>
> -- 
> Pedro Henrique de Souza Medeiros
> --
> Cel: +55 (21) 9914-86898
> Email: pedr...@gmail.com 
>
> Beautiful is better than ugly,
> Explicit is better than implicit,
> Simple is better than complex,
> Complex is better than complicated.
>
> The Zen of Python, by Tim Peters
>

-- 
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+unsu

[elixir-core:7779] Re: Why using "|" in a map is calling update instead of put ?

2018-01-19 Thread Ben Wilson
Notably, this mailing list is for proposals for the development of the 
language. General questions are better suited for the forums, slack, irc, 
or other more general discussion areas.

On Wednesday, January 17, 2018 at 5:11:01 AM UTC-5, mG S wrote:
>
> Any exemple about "avoid bugs but to allow potential optimizations" ? just 
> curious actually...
>
> Le mardi 16 janvier 2018 17:58:47 UTC+1, charlott...@gmail.com a écrit :
>>
>> as a side note, you can note that erlang has :maps.put (inserts/replace a 
>> k/v) and :maps.update (only replaces an existing kv),
>>
>> elixir mimics this by having Map.put for insert/replace and %{x | atom: 
>> :atom} for replace (note that Map.update/4 has a different behaviour and is 
>> too complex for this case where you simply want to set an specific value to 
>> a map that should have the expected key)
>>
>> On Tuesday, January 16, 2018 at 2:56:10 PM UTC-2, charlott...@gmail.com 
>> wrote:
>>>
>>> The syntax for updating maps (ie: `%{x | foo: :bar}`) assumes the key is 
>>> already set on the map, this is to, not only, avoid bugs but to allow 
>>> potential optimizations
>>>
>>> In https://hexdocs.pm/elixir/Map.html you can see that this is an 
>>> expected behaviour
>>>
>>> > Maps also support a specific update syntax to update the value stored 
>>> under *existing* atom keys:
>>>
>>> On Tuesday, January 16, 2018 at 2:16:24 PM UTC-2, mG S wrote:

 Hi everyone, 

 Well the whole question fits in the subject...
 I was wondering why the pipe operator used in a map was sugar for 
 Map.update and not Map.put

 iex(1)> m=%{foo: 1}
 %{foo: 1}
 iex(2)> %{m | bar: 2}
 ** (KeyError) key :bar not found in: %{foo: 1}
 (stdlib) :maps.update(:bar, 2, %{foo: 1})
 (stdlib) erl_eval.erl:255: anonymous fn/2 in :erl_eval.expr/5
 (stdlib) lists.erl:1262: :lists.foldl/3
 iex(2)> %{m | foo: 2}
 %{foo: 2}


 I'm sure it has good reasons, but I'm a little puzzled on why ?



-- 
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/ef39ecfc-8e92-4bfa-8272-b78e354b3528%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:7726] Re: Proposal: Inspect implementation for URI

2018-01-01 Thread Ben Wilson
The downside here is that you can no longer copy and paste the output.

On Monday, January 1, 2018 at 10:58:30 AM UTC-5, Wojtek Mach wrote:
>
> Hello,
>
> Having an Inspect implementation would make a shorter output in iex, 
> exunit diffs etc and the string representation is inambiguous. Under the 
> hood it would use `String.Chars.URI.to_string/1`.
> The only reason it might have been omitted that I can think of is how it 
> plays with `URI.default_port/2`:
>
> Before:
>
> iex(3)> URI.default_port("ponzi", 8080)
> :ok
>
> iex(4)> URI.parse("http://example.com:8080";)
> %URI{authority: "example.com:8080", fragment: nil, host: "example.com",
>  path: nil, port: 8080, query: nil, scheme: "http", userinfo: nil}
>
> iex(5)> URI.parse("ponzi://example.com:8080")
> %URI{authority: "example.com:8080", fragment: nil, host: "example.com",
>  path: nil, port: 8080, query: nil, scheme: "ponzi", userinfo: nil}
>
> iex(6)> URI.parse("ponzi://example.com")
> %URI{authority: "example.com", fragment: nil, host: "example.com", path: 
> nil,
>  port: 8080, query: nil, scheme: "ponzi", userinfo: nil}
>
>
>
> After:
>
> iex(2)> URI.default_port("ponzi", 8080)
> :ok
>
> iex(3)> URI.parse("http://example.com:8080";)
> #URI
>
> iex(4)> URI.parse("ponzi://example.com:8080")
> #URI
>
> iex(5)> URI.parse("ponzi://example.com")
> #URI
>
>
>
> so one could argue we lose a bit of information as the default port is 
> implicit. Was that the reason it was omitted? Otherwise, I'm happy to 
> prepare a PR.
>

-- 
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/d49e7236-6bee-4168-8170-410564788de5%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elixir-core:7468] [Proposal] Converting @type/@spec to contract/asserts at compile time?

2017-09-30 Thread Ben Wilson
No, there is intentionally no way to globally apply a macro.

On Saturday, September 30, 2017 at 7:42:54 AM UTC-4, gasp...@gmail.com 
wrote:
>
>
>
> On Saturday, September 30, 2017 at 2:36:30 PM UTC+3, Louis Pilfold wrote:
>>
>> Heya
>>
>> You could write a library that does this rather than modifying Elixir. It 
>> would be a cool project :)
>>
>> Cheers,
>> Louis
>>
>
> I wonder if I can redefine  'def' macro and inject it into every module 
> without modifying module to have 'use Something' in them.
>
> /Gaspar
>
>
>  
>
>>
>> On Fri, 29 Sep 2017, 18:06 ,  wrote:
>>
>>> Hi all!
>>>
>>> I increasingly find myself writing more or less exactly same logic as in 
>>> @type/@spec in body of the function to check incoming arguments.
>>>
>>> Would it be helpful if Elixir compiler could wrap function into assert 
>>> check for incoming arguments and also result generated based on typespec?
>>>
>>> I think it would be very useful for 
>>>
>>> - while running unit tests immediately see where components interaction 
>>> breaks
>>> - keeping unit tests data in sync while developing - creates more 
>>> crashes when some stub/test data does not comply with changed logic in 
>>> function
>>> - running system and checking where it breaks the contracts between 
>>> components in run-time/while debugging (dyalizer does a great job to 
>>> extract information during static analysis phase, but runtime can provide 
>>> more incorrect data :)
>>> - encourage writing more typespecs because benefits of doing so will be 
>>> visible immediately and not when (occasionally) dyalizer will be run. So 
>>> make it type specification first class citizen that is not just for 
>>> documenting code, but also to enforce constraints.
>>>
>>> I personally would also love to have possibility for extended typespec 
>>> that would allow also specify relation between arguments too. Like 
>>> assert(arg1 + arg2 > 0).
>>>
>>> It seems that it may be achieved mostly by rewriting def/defp macros and 
>>> embedding asserts code generated from @spec around function body.
>>>
>>> This will slow down the execution of code and should be compiler option 
>>> to turn it on/off for production/dev/testing environment separately with on 
>>> setting in development/testing by default.
>>>
>>> What do you think? 
>>>
>>> /Gaspar
>>>
>>> -- 
>>> 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/638bb1fe-5276-49a3-9013-a784625226ea%40googlegroups.com
>>>  
>>> 
>>> .
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>

-- 
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/b6b958cf-1987-4412-8e4e-c00d37af53c4%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:7449] Re: [Proposal] More intuitive import shadowing

2017-09-23 Thread Ben Wilson
Setting aside whether or not the existing functionality is intuitive or 
not, this isn't actually a proposal. You aren't suggesting an alternative.

On Thursday, September 21, 2017 at 10:17:12 AM UTC-4, Krzysztof Wende wrote:
>
> Right now when we import a module A
>
> defmodule CurrentA do
>   def public1, do: 1
>   def public2, do: 2
>   def public3, do: 3
> end
>
>
> defmodule CurrentA do
>   import CurrentA, only: [public1: 0]
>   import CurrentA
>   
>   def test, do: public2() # No problem whatsoever
> end
>
> But whenever we add `except` to it
>
> defmodule CurrentA do
>   def public1, do: 1
>   def public2, do: 2
>   def public3, do: 3
> end
>
>
> defmodule CurrentA do
>   import CurrentA, only: [public1: 0]
>   import CurrentA, except: [public3: 0]
>   
>   def test, do: public2() # undefined function public2/0
> end
>
> We get an error of inexistent function. For me it feels super 
> counter-intuitive.
>
> Thoughts?
> Cheers,
> Krzysztof
>

-- 
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/7f1e33c3-21d4-4c0f-b176-bdcc1fe35f81%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elixir-core:7347] Automatic inspect interpolation

2017-07-30 Thread Ben Wilson
Agreed. Inspect can leak sensitive information easily, and I think it's 
important to annotate that a structure will be using its debug 
representation in a string.

On Sunday, July 30, 2017 at 3:31:57 AM UTC-4, José Valim wrote:
>
> I personally prefer the clearer approach of calling "inspect" instead of 
> an operator.
>
>
>
> *José Valim*
> www.plataformatec.com.br
> Skype: jv.ptec
> Founder and Director of R&D
>
> On Sun, Jul 30, 2017 at 1:17 AM, niahoo osef  > wrote:
>
>> Hey, 
>>
>> I would like to know what you would think about a new interpolation 
>> mechanism that automatically calls `inspect` as the `#{}` operator calls 
>> `to_string` ?
>>
>> Just like `raise "bad value : #!{var}"` instead of `raise "bad value : 
>> #{inspect var}"` (The operator could be anything, I don't care)
>>
>> Thanks.
>>
>> -- 
>> 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/7da7971b-5abb-4ed2-afb1-4add2b4e0dca%40googlegroups.com
>>  
>> 
>> .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
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/4b09d0eb-ff2a-45a3-bac1-b6c0cfc8050d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:7150] Re: Proposal: pipe and assign syntax

2017-05-19 Thread Ben Wilson
This has been proposed before, and it was rejected then as well. You're 
only saving a few characters, and it obfuscates that two completely 
different things are happening (assignment, function calling).

On Friday, May 19, 2017 at 1:27:29 PM UTC-4, OvermindDL1 wrote:
>
> Actually that specific example would not work now that I think of it, but 
> you could do it via a bit more macro-work.
>
>
> On Friday, May 19, 2017 at 11:26:19 AM UTC-6, OvermindDL1 wrote:
>>
>> You could easily make that into a library (in fact similar ones already 
>> exist, though not for 'just' that feature).
>>
>> Just define a new operator, say `<|>` since you are piping 'both ways' 
>> I'd say as a macro, then you can do it, it might even be as simple as 
>> (untested):
>> ```elixir
>> defmacro left <|> right do
>>   quote do
>> unquote(left) = unquote(left) |> unquote(right)
>>   end
>> end
>> ```
>> Then you could do:
>> ```elixir
>> conn
>> <|> put_assign(:blah, :bloop)
>>  |> more_stuff()
>>  |> render(:index)
>> ```
>> or so.  Easily done as a library though, or just add it to your own 
>> project and require it where you want.
>>
>>
>>
>> On Friday, May 19, 2017 at 11:06:28 AM UTC-6, Mario Campa wrote:
>>>
>>> Hello, 
>>>
>>> I'm new to Elixir, so forgive me if this idea sounds silly.
>>>
>>> I keep repeating this pattern in multiple controllers:
>>>
>>> conn = Plug.Conn.put_session(conn, :foo, bar)
>>>
>>> or
>>>
>>> conn = conn |> Plug.Conn.put_session(:foo, bar)
>>>
>>>
>>> IMO it would be cool to have a shorter version to this where I can pipe 
>>> and assign like this:
>>>
>>> conn |>= Plug.Conn.put_session(:foo, bar)
>>>
>>>
>>> Similar to
>>>
>>> a = a + 2
>>> # or
>>> a += 2
>>>
>>>
>>>

-- 
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/14a96e51-b032-4907-903a-7d35df33b6e8%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elixir-core:7026] Passing the map to Map.get_lazy's function

2017-03-20 Thread Ben Wilson
Can you elaborate on the code you have in mind? This sounds like a general 
characteristic of pipes and not something specific to Map.get_lazy.

On Monday, March 20, 2017 at 6:48:46 AM UTC-4, David Long wrote:
>
> That's not entirely accurate. In my case I was using a series of pipes so 
> I did not have access to the map. My case might be very niche, though. 
>
> On Mon, Mar 20, 2017, 12:44 AM José Valim  > wrote:
>
>> The reason why get_lazy does not pass the map is because you already have 
>> the map, since you pass it as first argument.
>>
>> On Mon, Mar 20, 2017 at 03:44 David Long > > wrote:
>>
>>> I was working on some code that would simply test if one key was in a 
>>> map and return it's value, and otherwise return a different key's value.
>>>
>>> The map had a form like the following:
>>>
>>> %{
>>>   oncall: "dlong",
>>>   overrideoncall: "jsmith",
>>>   ...
>>> }
>>>
>>>
>>> If there was someone overriding on call then their name would be in the `
>>> overrideoncall` key, otherwise the key would not be in the map.
>>>
>>> I think this could be a nice use for `Map.get_lazy`, if the function had 
>>> the original map passed in, allowing me to write the code as follows:
>>>
>>> Map.get_lazy(on_call_group, :overrideoncall, &(&1[:oncall]))
>>>
>>>
>>> Before I wrote a pull request, I thought I'd see if this is a feature 
>>> that makes sense to others?
>>>
>>> -- 
>>>
>> 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/719dc4fc-ae23-4437-b059-d91356e9b43b%40googlegroups.com
>>>  
>>> 
>>> .
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>> -- 
>>
>>
>> *José Valim*
>> www.plataformatec.com.br
>> Skype: jv.ptec
>> Founder and Director of R&D
>>
>> -- 
>> You received this message because you are subscribed to a topic in the 
>> Google Groups "elixir-lang-core" group.
>> To unsubscribe from this topic, visit 
>> https://groups.google.com/d/topic/elixir-lang-core/JuAZnOXpo5Q/unsubscribe
>> .
>> To unsubscribe from this group and all its topics, 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/CAGnRm4J7dZWROSBnBU7Ayn%3DhQGphp_ciFZTRf83XscDTQQ2z3w%40mail.gmail.com
>>  
>> 
>> .
>> For more options, visit https://groups.google.com/d/optout.
>>
>

-- 
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/9f0334d6-c484-454e-8fe7-d236e2804f45%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:6887] Re: Sorting maps when inspecting

2017-02-14 Thread Ben Wilson
This has my vote as well. It would make visually inspecting maps a lot 
easier.

On Tuesday, February 14, 2017 at 7:36:05 PM UTC-5, Onorio Catenacci wrote:
>
> +1 Eric 

-- 
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/934ffbee-44a6-40fb-9ecf-e24d48624f3f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elixir-core:6832] [Proposal] Enum.sort for Dates

2017-01-21 Thread Ben Wilson
See an earlier discussion on a similar 
idea: https://groups.google.com/forum/#!topic/elixir-lang-core/eE_mMWKdVYY

On Friday, January 20, 2017 at 3:12:37 PM UTC-5, Paul Schoenfelder wrote:
>
> Sorry Josh, I should have replied to your original proposal. What I was 
> getting at is that you can already use the existing Enum sorting functions 
> with Dates, just by providing a sorter function, you don't have to convert 
> to/from. As José mentioned though, there isn't any way to make Enum.sort/1 
> itself work on structs, it's up to the struct implementor to define 
> functions which can be easily used with `Enum.sort_by` to make them 
> sortable, such as `DateTime.to_unix`. There have been previous 
> conversations on the mailing list about this subject, but I don't believe 
> any of them got to a point where there was a viable implementation.
>
> Paul
>
>
> On Fri, Jan 20, 2017 at 2:03 PM, Josh Crews  > wrote:
>
>> Hi. I love Timex so much!
>>
>> Regarding work around... I guess?
>>
>> What do you think of the main thread question, "should Enum.sort work on 
>> Date types"?
>>
>> On Friday, January 20, 2017 at 1:42:20 PM UTC-6, Paul Schoenfelder wrote:
>>>
>>> Probably easier to use `Enum.sort_by(dates, &DateTime.to_unix/1)`, no?
>>>
>>> Paul
>>>
>>> On Fri, Jan 20, 2017 at 1:39 PM, Josh Crews  wrote:
>>>
 Current behavior:


 iex(3)> [~D[2017-01-04], ~D[2017-04-03], ~D[2017-01-05]] |> Enum.sort

 [~D[2017-04-03], ~D[2017-01-04], ~D[2017-01-05]]


 Proposed:

 iex(3)> [~D[2017-01-04], ~D[2017-04-03], ~D[2017-01-05]] |> Enum.sort

 [~D[2017-01-04], ~D[2017-01-05], ~D[2017-04-03]]


 What I'm currently doing is:

 iex(4)> [~D[2017-01-04], ~D[2017-04-03], ~D[2017-01-05]] |> 
 Enum.map(&(Date.to_erl/1)) |> Enum.sort |> Enum.map(&(Date.from_erl!/1))

 [~D[2017-01-04], ~D[2017-01-05], ~D[2017-04-03]]


 which is working great, but would be cool to have Enum.sort work on 
 Date types too.

 -- 
 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/5cb8a9f9-ee03-497e-87d6-7bd9633b2f78%40googlegroups.com
  
 
 .
 For more options, visit https://groups.google.com/d/optout.

>>>
>>> -- 
>> 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/8a996168-b548-4730-a2a6-baa38a88d712%40googlegroups.com
>>  
>> 
>> .
>>
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
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/a20f87db-6137-42b8-9943-1d88aa141cc5%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elixir-core:6643] Adding __APP__ or something similar

2016-12-01 Thread Ben Wilson
FWIW I have renamed a couple enormous projects and in all cases it took 
basically 2 find and replace runs and a folder move.

-- 
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/cb303151-0ea1-4448-af05-5134603f1115%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:6612] Re: Elixir Getting Started Guide Section for `use`

2016-11-22 Thread Ben Wilson
The documentation is pretty thorough 
here: http://elixir-lang.org/docs/master/elixir/Kernel.html#use/2

Honestly, use isn't really beginner material. What do you mean by "start 
using module that he himself wrote" ?

On Tuesday, November 22, 2016 at 6:54:32 PM UTC-5, Razvan Musetescu wrote:
>
> I've been trying to figure out the best way to leverage the functionality 
> of module into other modules.
> Naturally I thought that one of the directives *require* or *import* or 
> the *use* macro would be the solution
> http://elixir-lang.org/getting-started/alias-require-and-import.html
>
> After doing some research I found that the use macro solved my problem but 
> I figured out how to use it just after reading this
> http://learningelixir.joekain.com/use-import-require-in-elixir/
>
> Specifically there's nothing in the Getting Started Guide about how should 
> we should write the __using__ macro.
> I believe this information should be available in the guide as the current 
> documentation isn't enough for a beginner to start using module that he 
> *himself* wrote.
>

-- 
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/be4c95d6-0f82-4bb7-928b-d1b33392205a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:6444] Re: proposal: functional assertions, a case for assert_equal, assert_match, and possibly more

2016-09-30 Thread Ben Wilson
When I think of imperative programming I think of programs with lots of 
statements that mutate state. When I think of functional programming I 
think of programs which model computation as inputs and outputs.

Elixir does have some impurity, but it has no statements, and pure 
functions constitute an enormous portion of what you write. I'm not sure 
"imperative functional language" is a thing.

This however is diverging heavily from the original topic.

On Friday, September 30, 2016 at 10:21:01 AM UTC-4, Eric Entin wrote:
>
> I think that unit tests such as they exist in Elixir, which is an 
> imperative functional language, IMO, are inherently imperative. Property 
> tests would be a nice example of a more declarative testing style.
>
> On Friday, September 30, 2016 at 1:01:30 AM UTC-4, Jaap Frolich wrote:
>>
>> Thanks,
>>
>> It seems that opinions differ about the incremental improvement of 
>> putting this in. After thinking about it I also think it is probably better 
>> to keep it simple in the core language, and no reason for it not to be a 
>> library for functional programming aficionados, and syntax nitpicks :). If 
>> you do not worry how your code looks indeed the same can be accomplished 
>> using:
>>
>> |> Kernel.==(expected_result)
>> |> assert
>>
>>
>> with match? we have to create a function to swap the arguments, and you 
>> can do the same.
>>
>> I published it as assert_functional (
>> https://hex.pm/packages/assert_functional), and I used it in the tests 
>> of another package (if you are interested how to apply it) if_ok (
>> https://hex.pm/packages/if_ok).
>>
>> Thanks for your feedback. Always interesting to build up a body of 
>> knowledge about how the community thinks about a particular subject.
>>
>> @eric: Why do you think they are both imperative, and how would you make 
>> them more declarative? Very interested!
>>
>> Cheers,
>>
>> Jaap
>>
>>
>> On Friday, September 30, 2016 at 1:51:14 AM UTC+8, Ben Wilson wrote:
>>>
>>> I also disagree that it's more declarative.
>>>
>>> In the standard ExUnit case, you have some setup code, and then the 
>>> assertion is a clear and easily distinct line. It's clear what is the 
>>> pattern, and what its being matched against.
>>>
>>> both = and the existing match? function take the pattern on the LHS so 
>>> assert_match in particular is a bit odd because it's now on the RHS.
>>>
>>> On Thursday, September 29, 2016 at 12:39:47 PM UTC-4, Eric Entin wrote:
>>>>
>>>> I disagree that the latter is more declarative than the former. They 
>>>> are just two different ways of writing the same thing. In fact, they're 
>>>> both fairly imperative. :)
>>>>
>>>> Pipes are awesome, but IMO they are a tool for convenience, and not the 
>>>> only way that clean, idiomatic Elixir code can be structured. I think the 
>>>> number of asserts that you will eventually have to implement here is 
>>>> another good argument against this, as people reading your code will now 
>>>> have to know both the standard Elixir operators as well as the names of 
>>>> the 
>>>> special matchers you create.
>>>>
>>>> I can definitely see your reasons for wanting this, so I think a 
>>>> library would be welcome, but I'm not in support of this being added to 
>>>> core at this time.
>>>>
>>>> On Thursday, September 29, 2016 at 6:23:45 AM UTC-4, Jaap Frolich wrote:
>>>>>
>>>>> Probably you have run into this: if you have slightly more complex 
>>>>> tests than testing the output of a single function, you need assignment 
>>>>> and 
>>>>> then assert that assignment with an operator. Consider this controller 
>>>>> test 
>>>>> in phoenix:
>>>>>
>>>>> conn =
>>>>>   build_conn()
>>>>>   |> post("/upload_content_cover", params)
>>>>>
>>>>>
>>>>> assert %{"success" => true} = json_response(conn, 200)
>>>>>
>>>>>
>>>>> with an `assert_match` function this translates to the following:
>>>>>
>>>>> build_conn()
>>>>> |> post("/upload_content_cover", params)
>>>>> |> json_response(conn, 200)
>>>>> |> assert_match(%{"success" => tru

[elixir-core:6430] Re: proposal: functional assertions, a case for assert_equal, assert_match, and possibly more

2016-09-29 Thread Ben Wilson
I also disagree that it's more declarative.

In the standard ExUnit case, you have some setup code, and then the 
assertion is a clear and easily distinct line. It's clear what is the 
pattern, and what its being matched against.

both = and the existing match? function take the pattern on the LHS so 
assert_match in particular is a bit odd because it's now on the RHS.

On Thursday, September 29, 2016 at 12:39:47 PM UTC-4, Eric Entin wrote:
>
> I disagree that the latter is more declarative than the former. They are 
> just two different ways of writing the same thing. In fact, they're both 
> fairly imperative. :)
>
> Pipes are awesome, but IMO they are a tool for convenience, and not the 
> only way that clean, idiomatic Elixir code can be structured. I think the 
> number of asserts that you will eventually have to implement here is 
> another good argument against this, as people reading your code will now 
> have to know both the standard Elixir operators as well as the names of the 
> special matchers you create.
>
> I can definitely see your reasons for wanting this, so I think a library 
> would be welcome, but I'm not in support of this being added to core at 
> this time.
>
> On Thursday, September 29, 2016 at 6:23:45 AM UTC-4, Jaap Frolich wrote:
>>
>> Probably you have run into this: if you have slightly more complex tests 
>> than testing the output of a single function, you need assignment and then 
>> assert that assignment with an operator. Consider this controller test in 
>> phoenix:
>>
>> conn =
>>   build_conn()
>>   |> post("/upload_content_cover", params)
>>
>>
>> assert %{"success" => true} = json_response(conn, 200)
>>
>>
>> with an `assert_match` function this translates to the following:
>>
>> build_conn()
>> |> post("/upload_content_cover", params)
>> |> json_response(conn, 200)
>> |> assert_match(%{"success" => true})
>>
>>
>> I prefer the latter, because it is more declarative. 
>>
>> My issue with using operators in assertions, is that while improving 
>> readability in some cases, they are not very functional constructs, and 
>> thus do not compose well. Having a functional equivalent for the 
>> assertions, makes sense in a functional language in my opinion.
>>
>> I can also see why this should be a library, keeping the assertion 
>> library less complex. Just would like to share my thinking. I'm also 
>> interested in feedback, and how I might be wrong :).
>>
>> See the following pull request for an implementation: 
>> https://github.com/elixir-lang/elixir/pull/5259.
>>
>

-- 
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/a2bb5b47-b92d-4278-896b-37e80307de76%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elixir-core:6352] Add mix release task similar to rake release

2016-09-21 Thread Ben Wilson
Problematically, Elixir already has a notion of what a "release" 
(http://erlang.org/doc/design_principles/release_structure.html) is and it 
has nothing to do with hex. We probably do not want to overload that term.

mix hex.publish is also already a thing, so we'd need some other name here.

On Wednesday, September 21, 2016 at 7:48:54 AM UTC-4, Allen Madsen wrote:
>
> I agree with Alexsei that it is pretty standard. If you want to do 
> something off the beaten path, you still have that option with the 
> individual commands available.
>
> Allen Madsen
> http://www.allenmadsen.com
>
> On Wed, Sep 21, 2016 at 7:29 AM, Alexsei Matiushkin <
> aleksei.m...@kantox.com > wrote:
>
>> For hex publishing, this process is more or less the same and it’s 
>> implicitly proven by `rake release` existence. I have no problem writing 
>> shell function, but in my opinion, mix task here is more appropriate since 
>> it has a direct access to the version and in shell I would parse `mix.exs` 
>> which is a bit ugly.
>>
>> Anyway, I got your reasoning, thx for reaching out.
>>
>> On Wed, Sep 21, 2016 at 1:19 PM, Louis Pilfold > > wrote:
>>
>>> Heya
>>>
>>> I'm not a fan of this as everyone will have a different steps in their
>>> release process.
>>>
>>> Personally I would just write a little shell script (or mix task) to do 
>>> this.
>>>
>>> Cheers,
>>> Louis
>>>
>>> On 21 September 2016 at 12:17, Alexsei Matiushkin
>>> > wrote:
>>> > It would be handy to have a mix task, similar to what rake release 
>>> does in
>>> > the ruby world
>>> > 
>>> https://github.com/bundler/bundler/blob/master/lib/bundler/gem_helper.rb#L55
>>> > :
>>> >
>>> > mix.compile
>>> > mix test
>>> > source control commit with tag=CURRENT_VERSION
>>> > mix hex.publish
>>> >
>>> > Everything save for the third item in this list might be easily done 
>>> with
>>> > shell alias/function, but this beast in the middle literally screws me 
>>> up:
>>> > sometimes I forget to push a tag, sometimes I forget to update a 
>>> version,
>>> > etc. It would be really great to implement the functionality that tries
>>> > tests, reads a version from mix.exs, uses it as a tag in commit, 
>>> publishes
>>> > to hex.pm if everything above succeeded.
>>> >
>>> > I could put some effort in implementing this, but I really need kinda
>>> > feedback on whether it’s needed and—if so—some guidance on how to 
>>> approach
>>> > it.
>>> >
>>> > Rgds, AM-73
>>> >
>>> > --
>>> > 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/0095086f-2c3d-4dce-9263-c71e72151486%40googlegroups.com
>>> .
>>> > For more options, visit https://groups.google.com/d/optout.
>>>
>>> --
>>> You received this message because you are subscribed to a topic in the 
>>> Google Groups "elixir-lang-core" group.
>>> To unsubscribe from this topic, visit 
>>> https://groups.google.com/d/topic/elixir-lang-core/MMB3ru8Rcxc/unsubscribe
>>> .
>>> To unsubscribe from this group and all its topics, 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/CAM-pwt5DQCck2G6G9B%3D7EMMBOs%3D0rnjjxHcBv%3D9gqXQZ_ynagw%40mail.gmail.com
>>> .
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>
>>
>> -- 
>>
>> *Alexsei Matiushkin*, Software Engineer - R&D
>>  
>> Office(+34) 935 679 834
>>  
>>  
>>
>> 6 Bevis Marks, London, EC3A 7BA, United Kingdom
>> Torre Mapfre, Planta 10, Marina, 16-18, 08005 Barcelona, Spain
>> *kantox.com *
>>  
>>  
>> [image: LinkedIn] 
>>  
>> [image: Twitter]   
>>[image: YouTube] 
>> 
>>  
>> Kantox Limited is registered in England and Wales as a Limited Company: 
>> No 07657495 and is authorised by the Financial Conduct Authority, FRN: 
>> 580343, as a Payments Institution under the Payment Services Regulations 
>> 2009. This email is subject to professional secrecy. It is confidential and 
>> for the exclusive use of its addressee. If you are not the addressee, you 
>> are not authorised to read, keep or disseminate it.
>>
>> -- 
>> 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-l

Re: [elixir-core:6325] Improvement: the syntax for importing functions from modules

2016-09-15 Thread Ben Wilson
Here's the thing. Right now import doesn't require any special syntax. It's 
data driven, and uses elixir structures that already exist and are usable.

Every single option you listed requires changes to the parser, new language 
constructs or both. All to do exactly what we can right now. I don't see 
the value.

On Thursday, September 15, 2016 at 10:11:09 AM UTC-4, Louis Pilfold wrote:
>
> Hello!
>
> What is the advantage of the new syntax? To me it seems it only serves to 
> obscure what is actually happening.
> I don't think adding multiple ways to write the same thing will bring 
> anything other than inconsistency to the language, causing style squabbles 
> and giving newcomers one more irregularity memorise.
>
> Side note: if this macro has a special syntax, does this mean I can also 
> use this syntax for my own macros?
>
> Cheers,
> Louis
>
> On 15 Sep 2016 10:39, "Jaap Frolich" > 
> wrote:
>
>> Hi,
>>
>> @Jose: I would suggest this to be syntactic sugar to import functions 
>> from modules, that is converted behind the scenes to a call to import, 
>> only: [...].
>> This will add complexity to the language, by creating a new way of 
>> importing, but in 99% you can use the new syntax, and only use the 'low 
>> level' syntax in macros or special use cases such as when you need 
>> 'except'. Another upside is that all the old code keeps working, but we 
>> have a nicer syntax for new code.
>> I think it can incentivize people to only import the necessary functions 
>> and not import all if there is a nicer syntax to it.
>>
>> @Onorio: While an improvement, I like the proposed syntax more, because 
>> in my opinion import a single/a few functions should be the default, and 
>> not a special case (with using only).
>>
>> @Norbert: I am not really in favor of the `import &function_one/1, 
>> &function_2/1 from Module` syntax as I think it is less pretty and while it 
>> might be easier to implement, semantically it does not really makes sense 
>> to me / is intuitive.
>>
>> Thanks for thinking about this :) Love the language.
>>
>> Cheers,
>>
>> Jaap
>>
>>
>>
>> On Tuesday, September 13, 2016 at 2:54:20 PM UTC+8, José Valim wrote:
>>>
>>> Thank you Jaap!
>>>
>>> The benefit of today's syntax is that the arguments are data, which 
>>> makes them easy to control and manipulate. Imagine you want to dynamically 
>>> import some data, how do you dynamically build a list or a tuple of 
>>> {defrecord/2, extract/2} entries?
>>>
>>> The data syntax is also what you get back from all of the introspection 
>>> functions in Elixir, such as String.__info__(:functions). Also, today's 
>>> syntax support `:except` and other options, which are not considered in the 
>>> new syntax.
>>>
>>> I would like to see those points considered before further considering a 
>>> new syntax.
>>>
>>>
>>>
>>> *José Valim*
>>> www.plataformatec.com.br
>>> Skype: jv.ptec
>>> Founder and Director of R&D
>>>
>>> On Tue, Sep 13, 2016 at 6:30 AM, Jaap Frolich  wrote:
>>>
 Hi,

 Currently when we import a single or a few functions from a module this 
 is the syntax to do it:

   import Record, only: [defrecord: 2, extract: 2]

 As this is something that is something quite common to do in a module, 
 the syntax can be more user-friendly in my opinion.

1. The notation for a function is captured in data, while normally 
we describe functions with the function/arity notation
2. By default it imports *everything*, as this is often not what 
you want, it might be better to make it more explicit
3. Aesthetics, but that might be personal, I think it does not read 
as nice

 So how about having something like below syntax in the language:

   import defrecord/2, extract/2 from Record

   import * from Record

 This might be hard to implement, other candidates could be:
   
   import {defrecord/2, extract/2}, from: Record
   
   import {*}, from: Record

 As it might be easier to implement in the language using macros.

 (while we keep the existing import macro around.)

 Let me know what you think!

 Cheers,

 Jaap

 -- 
 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/4e514d59-05bd-41c6-a1d5-a634b34ff350%40googlegroups.com
  
 
 .
 For more options, visit https://groups.google.com/d/optout.

>>>
>>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "elixir-lang-core" group.
>> To u

[elixir-core:6291] Re: IEx historial

2016-09-04 Thread Ben Wilson
I do think a first class solution would be best, but I have successfully used 
this library for a few years now. Installation for me was always as easy as 
just make install. 

-- 
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/854f3b5b-080a-4a75-8eaf-bc06618ea8ab%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:6289] Re: IEx historial

2016-09-02 Thread Ben Wilson
This library will add that ability: https://github.com/ferd/erlang-history

On Friday, September 2, 2016 at 3:29:17 PM UTC-4, michel perez wrote:
>
> can iex remember the past commands from other sessions when I use the up 
> key? that's how irb works it'll be a great feature
>

-- 
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/6d4368f6-1a6e-4604-bf9b-51cbb690ff06%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:6270] Re: Kernel.compare/2 and Comparable protocol

2016-08-29 Thread Ben Wilson
Because half the point of the comparable protocol is making it easy to compare 
numbers generically, where "numbers" can be any of integer, float, decimal, 
rational.

-- 
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/621b65fa-42f7-4507-95a2-c1124ba43ebb%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:6257] Re: [proposal] Consider supporting a map shorthand syntax

2016-08-28 Thread Ben Wilson
You necro'ed a thread that was effectively a year old, it isn't an ideal 
place to receive feedback.

Maybe try posting on the elixir forum?

On Sunday, August 28, 2016 at 1:13:55 PM UTC-4, Hassan Zamani wrote:
>
> No comments?
>
> On Saturday, August 13, 2016 at 2:53:56 PM UTC+4:30, Hassan Zamani wrote:
>>
>> I would appreciate hearing your thoughts on 
>> https://github.com/hzamani/synex. It has two macros: keys and params, 
>> first one for expansion of atom-value pairs in keyword lists, maps and 
>> structs, and other for expansion of string-value pairs in maps. Both of 
>> them have variable pinning and map update support and params supports 
>> nested maps:
>>
>> iex> params(%{a => %{b, c}}) = %{"a" => %{"b" => 2, "c" => 3}}
>> iex> a
>> %{"b" => 2, "c" => 3}
>> iex> c
>> 3
>>
>> Hassan
>>
>> On Wednesday, February 17, 2016 at 1:29:31 PM UTC+3:30, Jaap Frolich 
>> wrote:
>>>
>>> Very nice Johan,
>>>
>>> Love the power of macros. Is there any resolution if this will make the 
>>> standard library? I have a lot of repetition in my maps as well in my 
>>> current app, and this is one of the things I like in ES6 that I really miss 
>>> in Elixir (mostly it is of course the other way around ;)).
>>>
>>> Cheers,
>>>
>>> Jaap
>>>
>>> On Monday, August 10, 2015 at 4:57:02 PM UTC+8, Johan Wärlander wrote:

 After playing around a bit with the ~m sigil, I proposed a couple of 
 updates (one which touched on work that Andrea had alredy done, but with a 
 twist); short_maps now support the following:

 # Equality checks
 foo = 1
 bar = 2
 ~m(foo bar)a == %{foo: 1, bar: 2} #=> true

 # Matching
 ~m(foo bar)a = %{foo: 12, bar: "baaz"}
 foo #=> 12

 # Pinning (NEW)
 foo = 1
 ~m(^foo bar)a = %{foo: 1, bar: "baaz"} #=> %{foo: 1, bar: "baaz"}
 ~m(^foo bar)a = %{foo: 5, bar: "baaz"} #=> MatchError

 # Structs, when first word starts with '%' (NEW)
 defmodule Foo do
   defstruct bar: nil
 end
 ~m(%Foo bar)a = %Foo{bar: "baaz"}
 bar #=> "baaz"

 For anyone else interested, please do get the latest version from 
 Andrea's repository (https://github.com/whatyouhide/short_maps), then 
 play around with it and see how it feels.

 On Friday, June 19, 2015 at 12:02:36 PM UTC+2, Andrea Leopardi wrote:
>
> I stood against the %{foo, bar, baz} syntax and deemed that too 
> implicit, but I'm in favour of a possible ~m sigil. I think it may 
> still be a bit implicit, but I can see it would make code much more 
> concise 
> in a lot of situations. I took a stab at it and wrote a simple 
> implementation for such sigil, here 
> . We can try it out and 
> see if we like it (and please, have a look at the implementation as well 
> as 
> I'm not sure it's bulletproof).
>
>
>
> On Sunday, May 31, 2015 at 12:19:46 PM UTC+2, Devin Torres wrote:
>>
>> Taking a pretty cool page out of ES6:
>>
>> # If `method`, `url`, `headers`, and `payload` are already bound
>> %Request{method, url, headers, payload}
>>
>> # If e.g. `payload` hasn't been bound yet
>> %Request{method, url, headers, payload: get_payload()}
>>
>

-- 
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/debe0e81-410d-4312-b386-797d7929d6c6%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elixir-core:6254] Whitespace support for `with` clause

2016-08-25 Thread Ben Wilson
"/me really dislikes operators that do different things in different areas"

But that's exactly what happy makes the `=` operator do, and of all the 
operators in use `=` is by far the most used! `<-` effectively means "this 
is going to be bound according to the logic of the monad we're in". It 
isn't in common use outside of `for`, and `with` merely generalizes on that.

On Thursday, August 25, 2016 at 1:22:15 PM UTC-4, José Valim wrote:
>
>
> Testing, indeed it is not valid there.  :-)
>>
>> I wonder if it would be worth supporting such a case, I could report it 
>> in any case, done.  :-)
>>
>
> My point is that changing the AST is a slippery slope. I will likely 
> always find an example that fails because of precedence and mangling.
>
> Hmm, soft-matching operator, makes sense.  Any chance on updating the docs 
>> at 
>> http://elixir-lang.org/docs/stable/elixir/Kernel.SpecialForms.html#for/1 
>> where it states "Enumerable generators are defined using <-:" to 
>> something of that form, maybe like "`<-` matches on each given element and 
>> skips non-matches", although that still does not match how `with` does it.  
>> Hmm, it seems that `for` and `with` are using an identical operator in 
>> incompatible ways.
>>
>
> Improving the docs is a great idea. And again, the skipping or not is 
> defined by the enclosing with or for. All <- does is to check if something 
> matches. All you need to know is that the left side is a pattern.
>  
>
>> Hmm, having `when` be directly adjacent to `=` in precedence, what side 
>> effects would that have?  I do not think that `=` is allowed adjacent to a 
>> `when` that I can think of in function heads (which are the only other case 
>> where `when` is used that comes to immediate mind) so no issue there.
>>
>
> As mentioned in the previous email, it is related to the precedence of = 
> and when on the left side of ->. Play with the grammar and let us know if 
> you can make both "x when y = z" and "x = y when z -> w" work. Maybe if 
> both operators have the same precedence and are left associative?
>
>
>
> -- 
>
>
> *José Valim*
> www.plataformatec.com.br
> Skype: jv.ptec
> Founder and Director of R&D
>
>

-- 
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/a931841b-df8e-4d78-8565-c245842a5c52%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elixir-core:6192] Proposing backticks infix syntax for arity-2 functions

2016-08-11 Thread Ben Wilson
I'm confused what you mean by "What I am trying to get at, is that the new 
syntax lets you write binary functions in the same location as the 
guard-safe operators, which will make user-defined structs feel more 
integrated with the language." Your proposal still won't let `lt` be used 
in guard clauses, so I don't see how the guard clause discussion is 
relevant here.

At the end of the day the `` is exactly identical to |>, it just looks a 
bit different. I don't see the value in extra syntax to do something we can 
already do. That isn't to say that aesthetics never matters, but the 
difference here is merely that it doesn't emphasize the left hand side, 
whereas the |> operator does a little bit. That seems like entirely too 
little of a distinction to warrant extra syntax.

On Thursday, August 11, 2016 at 4:23:16 AM UTC-4, Aleksei Magusev wrote:
>
> I think backticks syntax makes sense for the Haskell since it has function 
> application via space, but for Elixir it hurts readability with no (visible 
> to me) benefits.
> Calling non-guard-safe function as the guard-safe operators doesn't feel 
> like a good thing: we remove valuable hint about function property in our 
> code.
>
> – Aleksei
>
> On Thursday, August 11, 2016 at 8:51:47 AM UTC+2, Wiebe-Marten Wijnja 
> wrote:
>>
>> Thank you for your replies!
>>
>> Indeed, the word 'guard' is missing from that sentence: The fact that 
>> Erlang only allows certain BIFs inside guard clauses, and therefore Elixir 
>> discouraging the overriding of operators that will not work in them. 
>>
>> This suggestion is not at all meant as a replacement for the pipeline 
>> operator |>.
>> The pipeline operator is built to accomodate the need to pass a single, 
>> most important, subject through a sequence of functions.
>> These functions that work on a single, most important subject, can be 
>> described as 'Take the left-hand side, and perform the action outlined by 
>> the rest of the parameters'.
>>
>>
>> However, the functions in the cases outlined above (arithmetic, 
>> comparisons, access, combinatorial, and there are probably more), it feels 
>> very weird, very unnatural to use the pipeline operator. 
>> These functions do not work on a single most important subject. Both the 
>> left-hand side and the right-hand side are equally important.
>> These can be described as 'Take the left-hand side and the right-hand 
>> side, and perform the action ontlined by the name of the operation.'
>>
>> Using these binary (arity-2) functions with the pipeline operator feels 
>> strange and distracts from what is going on: 
>> a |> div(b)
>> x |> lt?(y)
>> {1,2,3,4} |> elem(2)
>> %{foo: 1} |> Map.merge(%{bar: 2}) |> Map.merge(%{baz:3})
>>
>> The pipeline operator also stops to be useful in the case that we want to 
>> expand on the second argument of something:
>>
>> Observe that
>> Decimal.add(decimal_a, Decimal.div(decimal_b, Decimal.new(2)))
>> which the new syntax would let you write as
>> decimal_a `Decimal.add` (decimal_b `Decimal.div` Decimal.new(2))
>> was rewritten by Allen Madsen with the pipeline operator to
>> decimal_b |> Decimal.div(Decimal.new(2)) |> Decimal.add(decimal_a) 
>> which swaps the order of parameters passed into `Decimal.add`. For 
>> addition this is not a problem, but take a non-reflexive operation like 
>> subtraction:
>>
>> Decimal.sub(decimal_a,Decimal.div(decimal_b, Decimal.new(2)))
>> When using the pipeline operator, this would mean creating a call 
>> structure in this way:
>> Decimal.sub(decimal_a, decimal_b |> Decimal.div(Decimal.new(2)))
>> which would definitely be less readable than:
>> decimal_a `Decimal.sub` (decimal_b `Decimal.div` Decimal.new(2))
>>
>>
>> What I am trying to get at, is that the new syntax lets you write binary 
>> functions in the same location as the guard-safe operators, which will make 
>> user-defined structs feel more integrated with the language.
>> If you can do 
>> a > b
>> when a and b are built-in types, but are forced to use 
>> lg?(a, b)
>>  or 
>> a |> lg?(b)
>>  when having custom data types, I am not very happy.
>> But if I can use 
>> a `lg?` b
>> , I am. The semantics of the comparison are kept intact.
>>
>>
>> ~Wiebe-Marten/Qqwy
>>
>>
>>
>>
>> On Thursday, August 11, 2016 at 2:12:07 AM UTC+2, Ben Wilson wrote:
>>>
>>> I agree, this suggestion reads like the |> does not exist.
>>&

Re: [elixir-core:6187] Proposing backticks infix syntax for arity-2 functions

2016-08-10 Thread Ben Wilson
I agree, this suggestion reads like the |> does not exist.

I'm also not clear on what is meant by "One of the more longstanding 
problems in Elixir is the fact that there is a difference between how code 
is executed inside clauses and outside." What is a clause?

On Wednesday, August 10, 2016 at 7:48:39 PM UTC-4, Allen Madsen wrote:
>
> In my opinion, the pipeline operator already solves this problem. I 
> would rewrite some of your examples as follows: 
>
> decimal_b |> Decimal.div(Decimal.new(2)) |> Decimal.add(decimal_a) 
> Timex.today |> Timex.shift(days: 1) |> Timex.before?(Timex.today) 
> a |> div(b) 
> Allen Madsen 
> http://www.allenmadsen.com 
>
>
> On Wed, Aug 10, 2016 at 6:17 PM, Wiebe-Marten Wijnja 
> > wrote: 
> > One of the more longstanding problems in Elixir is the fact that there 
> is a 
> > difference between how code is executed inside clauses and outside. 
> > 
> > The choice was made to only define infix operators for the kinds of 
> > operations that are guard-safe, so it is not confusing as to when you 
> are 
> > and when you are not allowed to use these infix operators. 
> > 
> > There is another problem that operators have: They are very cryptic. The 
> > only way to know what an operator does, is if you've read its 
> definition, 
> > and still remember it. (Could you guess what `<|>`, `|^|` and `~?=` do 
> in 
> > Haskell?) 
> > 
> > Names of functions, on the other hand, are self-describing (as long as 
> they 
> > are named well, of course), so you instantly see what a piece of code 
> does. 
> > 
> > 
> > However, there are many operations that take two equally-important 
> > arguments, which are much more natural to write in an infix-style than 
> in a 
> > prefix-style, as this is also the direction in which we 'think' them in. 
> > 
> > Some common examples include: 
> > - Arithmetic operations like `+`, `-`, `*`, `/`, `div`, `mod`, `pow`. 
> > - Comparison operations like `>`, `<=`, `!=`, `match?`, 
> `MapSet.subset?`, 
> > `lt?`, `gte?`, `neq?`. 
> > - Access-based operations like the Access Protocol's `arr[x]`, `elem`, 
> > `put_in`, `List.delete`. 
> > - Operations that combine two structures, like `|`, `Map.merge`, 
> > `MapSet.intersection`. 
> > 
> > 
> > Because it is discouraged to override the infix operators for operations 
> > that are not (and often cannot be) guard-safe, it feels a little 
> 'clunky' to 
> > use custom data structures, as we're forced to do things like: 
> > Decimal.add(decimal_a, Decimal.div(decimal_b, Decimal.new(2)) 
> > 
> > Timex.before?(Timex.shift(Timex.today, days: 1), Timex.today) 
> > 
> > 
> > 
> > As Guy Steele said in his marvelous talk 'Growing a Language': "When 
> faced 
> > with this, programmers that are used to performing addition using a plus 
> > sign, quetch". (It is one of the most amazing talks I've ever seen, by 
> the 
> > way. I totally recommend tha you watch it right now.) 
> > 
> > If there were a way to use an infix notation for non-operators, users 
> could 
> > instead improve on the language in a "smooth and clean" way. 
> > 
> > 
> > Taking inspiration from Haskell's syntax, I realized that there is a way 
> to 
> > circumvent this problem: 
> > 
> > My proposal: Introduce backtick-syntax to use arity-2 functions inline. 
> > 
> > - Functions (and macros) with arity 2, can be written as 
> > a `div` b 
> > This is rewritten during compilation into 
> > div(a, b) 
> > 
> > 
> > Some more examples: 
> > users[1][:name] `put_in` "José" 
> > {x, _} `match?` foo 
> > {1, 2, 3} `elem` 2 
> > 
> > 
> > - Both local and remote functions can be called this way. The following 
> is 
> > thus also valid: 
> > %{a: 1, b: 2} `Map.merge` %{c: 3, d: 4} 
> > ["foo", "bar", "baz"] `List.delete` "bar" 
> > 
> > 
> > - This rewriting happens from left-to-right,(left-associative) so: 
> > import Map 
> > a `merge` b `merge` c 
> > is rewritten into: 
> > merge(merge(a, b), c) 
> > 
> > 
> > As far as I know, this is completely backwards-compatible: Backticks are 
> not 
> > allowed inside Elixir syntax right now. 
> > The only place where they are 'used' is inside documentation strings, to 
> > delimit in-line markdown code snippets. 
> > This is not a problem, however; To create an in-line code snippet that 
> > allows backticks to be used internally, one can simply delimit it with 
> two 
> > backticks. This is already used inside the documentation of Elixir 
> itself, 
> > such as on the page about writing documentation. 
> > 
> > --- 
> > 
> > 
> > Adding infix backtick-syntax is better than the current situation, 
> because: 
> > - It allows a more natural syntax for binary operations, making the 
> language 
> > more readable. 
> > - It makes custom data structures feel more integrated into the 
> language. 
> > 
> > This solution is better than 'just adding more possible operators' 
> because: 
> > - It keeps it very clear what is allowed inside guard-clauses and what 
> > isn't. 
> > - It is explicit what an oper

[elixir-core:6157] Re: defprotocol bug?

2016-08-01 Thread Ben Wilson
As shown in the documentation on defprotocol, you need to define a struct 
in the D4.Activity module, and then pass a %D4.Activity{} struct to the 
protocol function. As it is you're just passing in a module name which is 
an Atom, and there is no protocol implementation for atoms.

On Monday, August 1, 2016 at 2:54:29 PM UTC-4, Maximiliano Guzenski wrote:
>
> Hi, 
> I'm trying a simple to implement defprotocol/defimpl but I recevei always 
> a error:
> ps.: Activity is a Ector module, I using phoenix
>
> defprotocol D4.Policy do
>   def scoped(a, query, conn)
> end
>
> defimpl D4.Policy, for: D4.Activity do
>   def scoped(a, query, conn) do
> IO.puts "hi"
>   end
> end
>
> D4.Policy.scoped(D4.Activity, 1, 2)
>
> error -->
>
> ** (Protocol.UndefinedError) protocol D4.Policy not implemented for 
> D4.Activity
>
> (d4) web/lib/policy.ex:1: D4.Policy.impl_for!/1
>
> (d4) web/lib/policy.ex:3: D4.Policy.scoped/3
>
>

-- 
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/10a5782e-a154-4ffd-82cd-119d58709d61%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:6143] Re: why are zero arity anonymous functions not allowed?

2016-07-20 Thread Ben Wilson
The title is a bit misleading as it implies that Elixir doesn't have `fn -> 
"yo" end`, but at least that's cleared up in the body.

I do think it can be useful, IE `Task.async(&foo(args))` is more succinct 
than `Task.async(fn -> foo(args) end)`. Spawning processes and the like are 
about the only cases I can think of where zero arity functions are used 
frequently, but it does seem like it would be a win for consistency and 
readability in certain cases.

Perhaps there are ambiguities introduced however without &1 and friends? 
I'm sure one of the core team members will clarify.

On Wednesday, July 20, 2016 at 8:01:01 PM UTC-4, Scott Parish wrote:
>
> It seems inconsistent that the anonymous function sugar is not allowed for 
> zero arity functions. Is there a good reason for this, or did this need to 
> be proposed as a feature request instead of a bug?
>
> Reference: https://github.com/elixir-lang/elixir/issues/5042
>
> Thanks
>
>

-- 
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/41bfc1d9-fce2-46f1-b72b-5429d0f4fc6b%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:6136] Re: Proposal: Add String.from_codepoint/1

2016-07-18 Thread Ben Wilson
I too think that <> is perfectly adequate.

Obviously the proposed function also lets you do "1F916" but I can't think 
of a use case I've ever seen where that's necessary.

On Monday, July 18, 2016 at 11:58:27 AM UTC-4, Nathan Long wrote:
>
> Hi! I propose adding String.from_codepoint/1
>
> Example uses:
>
> String.from_codepoint(97)  # => "a"
> String.from_codepoint(128_518) # => "😆"
> String.from_codepoint("1F916") # => "🤖"
>
> I've personally wanted this while playing around with Elixir's unicode 
> support.
>
> I'm not sure whether this would ever be useful in production code, but it 
> seems nice to me to have something symmetrical to `?a`.
>
> The question has at least been poised before 
> 
> .
>
> José has said "I am not a big fan of it exactly because we can write it 
> today as `<>`" when I made a pull request 
> , but he suggested I 
> float the idea here.
>
> String.from_codepoint would be more discoverable and easier to use; it 
> would handle hexadecimal, which is how codepoints are usually referenced.
>
> Thoughts?
>

-- 
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/a304b14f-1cbb-4325-8722-ad66f3d9fb1d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elixir-core:6135] Proposal: Add Enum.at!/2

2016-07-18 Thread Ben Wilson
Enum.fetch! returns simply the item 
itself. http://elixir-lang.org/docs/master/elixir/Enum.html#fetch!/2

fetch returns the tuples.

On Monday, July 18, 2016 at 11:55:08 AM UTC-4, eksperimental wrote:
>
> it doesn't (other than one returns a tuple and another the element 
> itself), 
> but same thing as Myron Marston mentioned, 
> it is useful when used in pipelines. 
>
> If we decide not to included. We should mention that in the at/3 docs. 
>
>
> On Mon, 18 Jul 2016 17:33:24 +0200 
> José Valim > wrote: 
>
> > How Enum.at!/2 would be different from Enum.fetch!/2? 
> > 
> > 
> > 
> > *José Valim* 
> > www.plataformatec.com.br 
> > Skype: jv.ptec 
> > Founder and Director of R&D 
> > 
> > On Mon, Jul 18, 2016 at 5:28 PM, eksperimental 
> > > wrote: 
> > 
> > > Hi everyone. 
> > > I think if we have Enum.at/3 we should also have Enum.at!/2 
> > > 
> > > as with Enum.at/3 there is no way to guarantee that certain index 
> > > doesn't exist, since the default value could be contained in any of 
> > > the indexes. 
> > > 
> > > The only option is to use Enum.fetch!/2 
> > > 
> > > what do you guys think of this? 
> > > 
> > > -- 
> > > 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/20160718222830.4f1c21d4.eksperimental%40autistici.org
>  
> > > . 
> > > For more options, visit https://groups.google.com/d/optout. 
> > >   
> > 
>
>

-- 
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/a89c6152-f54f-4f92-857e-0c194fdc0e3f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elixir-core:6107] Tagging IO.inspect

2016-07-15 Thread Ben Wilson
Do we want to use #=> instead of => to make it clear it isn't showing some 
kind of map like syntax?

On Friday, July 15, 2016 at 9:14:05 AM UTC-4, Eric Meadows-Jönsson wrote:
>
> Another reason for the tag is that you can use it in a pipeline. If I have 
> long pipeline I am debugging I like to sprinkle some `|> IO.inspect` 
> between the lines to see what's going on in each pipeline stage. And when 
> piping it's of course not possible to wrap the value in a tuple.
>
> Big +1 from me for this feature.
>
> On Fri, Jul 15, 2016 at 12:11 PM, Michał Muskała  > wrote:
>
>> Ok, I will work on it.
>>
>> On 15 Jul 2016, at 12:07, José Valim > > wrote:
>>
>> Good points Andrea. Yes, let's ship this then.
>>
>>
>>
>> *José Valim*
>> www.plataformatec.com.br
>> Skype: jv.ptec
>> Founder and Director of R&D
>>
>> On Fri, Jul 15, 2016 at 12:00 PM, Andrea Leopardi > > wrote:
>>
>>> I love this feature, but I am against wrapping in a tuple because then 
>>> you may wonder if you are inspecting a tuple or something with :tag. 
>>> Instead, if you have "my list: ..." it will not be like any other inspected 
>>> term, so very easy to understand. Wdyt? :)
>>>
>>>
>>> Andrea Leopardi
>>> an.le...@gmail.com 
>>>
>>> On Fri, Jul 15, 2016 at 11:57 AM, José Valim <
>>> jose@plataformatec.com.br > wrote:
>>>
 I like this suggestion. I am wondering though if the tagging should be 
 done by wrapping the input in a tuple:

 IO.inspect([1, 2, 3], tag: “my list”)
 #=> {"my list", [1, 2, 3]}


 If not, we should probably just print: "my list: [1, 2, 3]".



 *José Valim*
 www.plataformatec.com.br
 Skype: jv.ptec
 Founder and Director of R&D

 On Fri, Jul 15, 2016 at 11:50 AM, Michał Muskała >>> > wrote:

> Hello everybody.
>
> IO.inspect/2 is one of the most useful debugging tools, and I use it 
> extremely often. The ability to stick `|> IO.inspect` in pretty much 
> every 
> part of the program is really powerful. Unfortunately when having 
> multiple 
> such calls it becomes hard to distinguish which output matches which call.
> The usual way to solve this is by inspecting something like {tag_name, 
> value} instead of just value, but this has the unfortunate effect of 
> breaking the pipe-ability and forces you to assign things into specific 
> variables.
>
> I propose we add an option to IO.inspect called tag. It would simply 
> print the tag before the output. How would it look like?
>
> IO.inspect([1, 2, 3], tag: “my list”)
>
> would print:
>
> my list => [1, 2, 3]
>
> The return value would obviously not change, so it would still be a 
> list [1, 2, 3] in that case. This still allows IO.inspect to be pipe-able 
> and gives us easily distinguishable output at the same time. I think this 
> would streamline the debugging experience and make IO.inspect even more 
> powerful.
>
> Michał.
>
> --
> 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/E807B41E-B89A-43CD-B55D-60A742B55BBC%40muskala.eu
> .
> For more options, visit https://groups.google.com/d/optout.
>


 -- 
 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/CAGnRm4%2BUhyhgMDdNy0gJk2Pm_eafm_n6SBViXmjiq8AWepEBeQ%40mail.gmail.com
  
 
 .

 For more options, visit https://groups.google.com/d/optout.

>>>
>>>
>>> -- 
>>> 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/CAM9Rf%2BL60EKrTAaP0VZ%2BcsSnff5ffQuZVHOkS__qQdBTRmJi1Q%40mail.gmail.com
>>>  
>>> 
>>> .
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "elixir-lang-core" group.
>> To unsubscrib

Re: [elixir-core:6073] Proposal: Add optional `into:` argument to Enum.map

2016-07-08 Thread Ben Wilson
I looked at having a fast path for Enum.into when I did the original Map.new 
upgrades and we decided against it. When the goal is to create a map from 
scratch |> Map.new is the clearest way to write that. The fast path for 
Enum.into would require that the second arg is BOTH a map AND an empty map, 
otherwise you can't use Map.new. If Enum.into(%{}) were the best way to create 
a new map from some other thing it would be worth the extra code path but I see 
Map.new as superior for that purpose. 

I do agree that documentation in Enum could mention that. I'm inclined to stick 
it in the moduledoc though because it applies to conceptually to the whole 
module. By way of example, it's just as relevant to filter as it is to map. 

-- 
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/645bf181-0cbc-4aff-b456-a6cb791f88aa%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elixir-core:6064] Proposal: Add optional `into:` argument to Enum.map

2016-07-07 Thread Ben Wilson
Not for lists it 
doesn't 
https://github.com/elixir-lang/elixir/blob/cbe03987daa9c01a9d7ce99137a1d76535efb5f9/lib/elixir/lib/enum.ex#L1185

Enum.map is for all intents and purposes exactly as fast as :lists.map. 
:maps.fold just converts a map to a list and folds over it, and then turns 
it back into a map.

On Thursday, July 7, 2016 at 6:25:28 PM UTC-4, Peter Hamilton wrote:
>
> To be fair, :maps.map is the fastest. But it's about as fast as :lists.map 
> . Enum has a lot of overhead.
>
> On Thu, Jul 7, 2016 at 3:23 PM Ben Wilson  > wrote:
>
>> This is correct. map |> Enum.map(&fun) |> Map.new is the fastest possible 
>> way to take a map and iterate over all of its keys.
>>
>> Reason being, building a new list of {k, v} pairs and calling the 
>> `:maps.from_list` NIF always beats out N Map.put calls, which is how into: 
>> %{} works. It also creates less garbage. Map.new is basically just 
>> :maps.from_list if it gets passed a list.
>>
>>
>> On Thursday, July 7, 2016 at 2:48:39 PM UTC-4, Michał Muskała wrote:
>>
>>> What do you mean by not converting to a list?
>>> The fastest way right now of doing a map on a map is actually to convert 
>>> to list, map and convert back to a map.
>>> I’d suspect that’s the case with a lot of data structures as well, 
>>> actually. Lists are simply really good for recursion.
>>> The benefit is even greater if you do multiple operations on those 
>>> lists, as the conversion happens (ideally) only
>>> once.
>>>
>>> Michał.
>>>
>>> On 07 Jul 2016, at 19:35, Peter Hamilton  wrote:
>>>
>>> Does the Enumerable protocol enable the performance improvement of not 
>>> converting to a list? I don't think it does.
>>>
>>> On Thu, Jul 7, 2016, 10:24 AM Andrea Leopardi  
>>> wrote:
>>>
>>> Enum.into/3 should do what you want :)
>>>>
>>>> On Thursday, 7 July 2016, Wiebe-Marten Wijnja  
>>>> wrote:
>>>>
>>>>> I propose to add `into: collectable` as optional third argument to 
>>>>> Enum.map. 
>>>>>
>>>>> This would allow mapping over things without first converting it to a 
>>>>> list and then convert it back.
>>>>>
>>>>> So:
>>>>>
>>>>> %{"a" => 1, "b" => 2}
>>>>> |> Enum.map(fn {k, v} -> {String.upcase(k), v} end)
>>>>> |> Enum.into(%{})
>>>>>
>>>>> could be written as:
>>>>>
>>>>> %{"a" => 1, "b" => 2}
>>>>> |> Enum.map(fn {k, v} -> {String.upcase(k), v} end, into: %{})
>>>>>
>>>>> Not having to do the list conversion in the middle might also improve 
>>>>> performance.
>>>>>
>>>>>
>>>>> Right now, enumerating and collecting in one go is of course possible 
>>>>> using `Kernel.SpecialForms.for`. `for` is however not very 
>>>>> pipeline-friendly.
>>>>>
>>>>>
>>>>> What do you think?
>>>>>
>>>>>
>>>>> Sincerely,
>>>>>
>>>>> ~Wiebe-Marten
>>>>>
>>>>> -- 
>>>>> 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/23c345b9-9ba1-48ea-8db0-6d2e9e700473%40googlegroups.com
>>>>>  
>>>>> <https://groups.google.com/d/msgid/elixir-lang-core/23c345b9-9ba1-48ea-8db0-6d2e9e700473%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>> .
>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>
>>>>
>>>>
>>>> -- 
>>>>
>>>
>>>> Andrea Leopardi
>>>> an.le...@gmail.com
>>>>
>>>
>>>>
>>>> -- 
>>>> 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

Re: [elixir-core:6062] Proposal: Add optional `into:` argument to Enum.map

2016-07-07 Thread Ben Wilson
This is correct. map |> Enum.map(&fun) |> Map.new is the fastest possible 
way to take a map and iterate over all of its keys.

Reason being, building a new list of {k, v} pairs and calling the 
`:maps.from_list` NIF always beats out N Map.put calls, which is how into: 
%{} works. It also creates less garbage. Map.new is basically just 
:maps.from_list if it gets passed a list.

On Thursday, July 7, 2016 at 2:48:39 PM UTC-4, Michał Muskała wrote:
>
> What do you mean by not converting to a list?
> The fastest way right now of doing a map on a map is actually to convert 
> to list, map and convert back to a map.
> I’d suspect that’s the case with a lot of data structures as well, 
> actually. Lists are simply really good for recursion.
> The benefit is even greater if you do multiple operations on those lists, 
> as the conversion happens (ideally) only
> once.
>
> Michał.
>
> On 07 Jul 2016, at 19:35, Peter Hamilton  > wrote:
>
> Does the Enumerable protocol enable the performance improvement of not 
> converting to a list? I don't think it does.
>
> On Thu, Jul 7, 2016, 10:24 AM Andrea Leopardi  > wrote:
>
>> Enum.into/3 should do what you want :)
>>
>> On Thursday, 7 July 2016, Wiebe-Marten Wijnja > > wrote:
>>
>>> I propose to add `into: collectable` as optional third argument to 
>>> Enum.map. 
>>>
>>> This would allow mapping over things without first converting it to a 
>>> list and then convert it back.
>>>
>>> So:
>>>
>>> %{"a" => 1, "b" => 2}
>>> |> Enum.map(fn {k, v} -> {String.upcase(k), v} end)
>>> |> Enum.into(%{})
>>>
>>> could be written as:
>>>
>>> %{"a" => 1, "b" => 2}
>>> |> Enum.map(fn {k, v} -> {String.upcase(k), v} end, into: %{})
>>>
>>> Not having to do the list conversion in the middle might also improve 
>>> performance.
>>>
>>>
>>> Right now, enumerating and collecting in one go is of course possible 
>>> using `Kernel.SpecialForms.for`. `for` is however not very 
>>> pipeline-friendly.
>>>
>>>
>>> What do you think?
>>>
>>>
>>> Sincerely,
>>>
>>> ~Wiebe-Marten
>>>
>>> -- 
>>> 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/23c345b9-9ba1-48ea-8db0-6d2e9e700473%40googlegroups.com
>>>  
>>> 
>>> .
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>
>> -- 
>>
>> Andrea Leopardi
>> an.le...@gmail.com 
>>
>>
>> -- 
>> 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/CAM9Rf%2BLY6tyh%3DE6iM%2BA7rmyY8dKP-ddCJpB%2BWZDn0jCuJ7FKaA%40mail.gmail.com
>>  
>> 
>> .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
> -- 
> 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/CAOMhEnyR_50BhVdVugiQqDUxY9jUBNRCR23Bao%3DhwQ9Zmeh4PA%40mail.gmail.com
>  
> 
> .
> For more options, visit https://groups.google.com/d/optout.
>
>
>

-- 
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/af052020-b329-49e0-a7b7-f0bf487c123c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elixir-core:5929] Proposal: Pretty print integers with underscore digit separator

2016-06-20 Thread Ben Wilson
Absinthe GraphQL will handle this fine. Arguably we shouldn't be using 
inspect there anyway, but these changes would be compatible regardless.

I'm also +1 about this change.

On Monday, June 20, 2016 at 3:56:43 PM UTC-4, José Valim wrote:
>
> Thanks Peter!
>
>
>
> *José Valim*
> www.plataformatec.com.br
> Skype: jv.ptec
> Founder and Director of R&D
>
> On Mon, Jun 20, 2016 at 7:24 PM, Peter Hamilton  > wrote:
>
>> The specific case I'm worried about is using inspect on a map and then 
>> using that result in something that is expected to be deterministic (like 
>> using it as a key in Redis).
>>
>>
>> I did a quick search on Github for Elixir repositories using inspect as 
>> to_string. I found 4 cases where inspect was used outside of generating 
>> user readable strings.
>>
>> That one is basically assuming that inspect() will 
>> output valid javascript. If a long integer were in that list it would cause 
>> a javascript error (I don't know if that's prevented elsewhere in the code 
>> or not):
>>
>> https://github.com/commentingon/DeepDive_PlugAndCowboy/blob/1ad46dad51543f39de8f3914ea5fc2f7a5624e9a/step_6/templates/rooms.html.ex#L61
>>
>> This one is probably fine because `plural` will be a string:
>>
>> https://github.com/phoenixframework/phoenix/blob/b9e4ae9f658108d1def9a32c27b06c318ae67a98/priv/templates/phoenix.gen.model/model.ex#L4
>>
>> This one is interesting because it assumes that Code.eval(inspect(a)) == 
>> a, which brings up the question of whether we allow underscores in integers 
>> in our code? (Yes we do, so that's good):
>>
>> https://github.com/mkremins/alembic/blob/2ae459201220b63af083d0d54325af93afa877f1/lib/config.ex#L47
>>
>> That one is over my head. I don't know enough about absinthe to quickly 
>> figure out whether it would be a problem.
>>
>> https://github.com/absinthe-graphql/absinthe/blob/43c27219d7f289baf4dae36b1a5596d0a2235072/lib/absinthe/type/built_ins/introspection.ex#L263
>>
>>
>> I completely agree that it is a bad practice to use inspect as to_string 
>> in deterministic situations. However, this would be a really really painful 
>> bug if someone were to use inspect(map_with_long_int) as a key in a 
>> datastore. All unit tests would likely pass because any new entries would 
>> reflect the new behavior, but in production existing entries would be 
>> orphaned and cause a pretty big fire (rolling back would also be a 
>> nightmare because new entries would then be orphaned with the old code).
>>
>> I'm in favor of it being the new default, but messaging must be very 
>> clear here and disabling it should be part of that messaging.
>>
>> On Mon, Jun 20, 2016 at 9:50 AM José Valim > > wrote:
>>
>>> > I'm nervous about existing inspect abuse as a hacky to_string. 
>>>
>>> What do you mean?
>>>
>>> >  I could see someone using it and feeding the result into a hashing 
>>> function and this change would break such an implementation.
>>>
>>> Using something like this today is already broken in all kinds of ways 
>>> that I am not particularly concerned about it. :)
>>>
>>>
>>>
>>> *José Valim*
>>> www.plataformatec.com.br
>>> Skype: jv.ptec
>>> Founder and Director of R&D
>>>
>>> On Mon, Jun 20, 2016 at 6:44 PM, Peter Hamilton >> > wrote:
>>>
 I'm nervous about existing inspect abuse as a hacky to_string. I could 
 see someone using it and feeding the result into a hashing function and 
 this change would break such an implementation.

 Being able to turn it off is probably sufficient. Would it make sense 
 to turn it off at a global level?

 On Mon, Jun 20, 2016, 9:38 AM José Valim >>> > wrote:

> I like this proposal. I would even pick it is a default with an option 
> to turn it off. Does anyone else have feedback? :)
>
>
>
> *José Valim*
> www.plataformatec.com.br
> Skype: jv.ptec
> Founder and Director of R&D
>
> On Tue, Jun 14, 2016 at 11:22 PM, Wojtek Mach  > wrote:
>
>> Hello everyone,
>>
>> It's very convenient to write down integer literals as e.g. 
>> 10_000_000 - much easier for humans to read.
>>
>> I was recently debugging some performance issues and I was working 
>> with this data in iex:
>>
>> [memory: 173978912, message_queue_len: 0, heap_size: 12834421,
>>   total_heap_size: 21747214,
>>   garbage_collection: [min_bin_vheap_size: 46422, min_heap_size: 233,
>>fullsweep_after: 65535, minor_gcs: 2]]
>>
>> This data would be *much* more readable to me with digit separators:
>>
>> [memory: 173_978_912, message_queue_len: 0, heap_size: 12_834_421,
>>   total_heap_size: 21_747_214,
>>   garbage_collection: [min_bin_vheap_size: 46_422, min_heap_size: 233
>> ,
>>fullsweep_after: 65_535, minor_gcs: 2]]
>>
>> It probably shouldn't be the default behavior for inspect/2, so I 
>> think this could only happen with one of: [pretty: true] , [pretty: 
>> :decimal]or perhaps so

[elixir-core:5922] Re: Proposal: Map.filter_values and Map.filter_keys

2016-06-20 Thread Ben Wilson
That turns out to actually be worse believe it or not. Reducing a map 
converts it to a list to begin with because there aren't built in map 
iterators. :maps.fold is really must :lists.foldl(:maps.to_list(map)). So 
given a list of key value pairs, it is actually fastest to build an 
intermediary list with just the desired key value pairs, and then call 
`:maps.from_list` on the result. You can read about that and other related 
stuff here: https://github.com/elixir-lang/elixir/pull/4415

As you'll see in that PR, that's actually how Map.take 
works 
https://github.com/elixir-lang/elixir/blob/e26f8de5753c16ad047b25e4ee9c31b9a45026e5/lib/elixir/lib/map.ex#L329.
 
In OTP 19 there's a NIF for take specifically but the point stands. 
Successive Map.put calls are actually suboptimal.

Stepping back a bit, there are a LOT of functions in Enum that logically 
apply to a map. Should we duplicate all of them in Map just to avoid a `|> 
Map.new` function call? 

On Saturday, June 18, 2016 at 4:49:04 PM UTC-4, Filip Haglund wrote:
>
> Here's another implementation, using Enum.reduce, without an intermediate 
> list: 
>
> def map_filter_values(map, func) do
>   Enum.reduce map, %{}, fn {key, val}, acc ->
> if func.(val) do
>   Map.put(acc, key, val)
> else
>   acc
> end
>   end
> end
>
>
> On Saturday, June 18, 2016 at 6:27:07 PM UTC+2, Filip Haglund wrote:
>>
>> I wish there was a Map.filter_values function that would filter on keys 
>> or values, but leave the other one intact. This seems like something that 
>> should be in the standard library.
>>
>> Example implementation of a Map.filter_values that would filter a map 
>> based on its values, leaving the keys intact:
>>
>> @doc """
>> Filter map based on its values, leaving the corresponding keys intact.
>> """
>> @spec map_filter_values(Map.t, (any -> boolean)) :: Map.t
>> def map_filter_values(map, func) do
>>   map |> Enum.filter(fn {_, val} -> func.(val) end) |> Map.new
>> end
>>
>>
>>
>> A corresponding Map.filter_keys would also be nice.
>>
>

-- 
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/630020c8-e8b4-4355-9d4f-2092b3cb914d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elixir-core:5920] Re: Proposal: Map.filter_values and Map.filter_keys

2016-06-18 Thread Ben Wilson
Stepping back for a moment, there are a lot of functions in the Enum module 
that apply to maps. Are we to implement all of them in the Map module just 
to avoid having to call Map.new after our various Enum calls?

The way things work at the moment is that when we need to take one item out 
at a time we convert the map to a list. This is not only semantically 
sensible, it's also efficient and fast. Once we have that list we leave it 
as a list so that we can easily compose these operations. If we no longer 
want a list, we can build a new map. This is also the fastest way to go 
about this.

On Saturday, June 18, 2016 at 9:26:20 PM UTC-4, Allen Madsen wrote:
>
> I have used the pattern this code wraps often and would use this 
> feature if it existed. 
> Allen Madsen 
> http://www.allenmadsen.com 
>
>
> On Sat, Jun 18, 2016 at 8:39 PM, Ben Wilson  > wrote: 
> > Well I tried to reply but my email was deleted. 
> > 
> > Long story short, successive Map.put calls are actually inferior to 
> walking 
> > intermediary lists and building a new map at the end. You can read more 
> > about it here: https://github.com/elixir-lang/elixir/pull/4415 
> > 
> > You'll note that Map.take is actually built in just that way: 
> > 
> https://github.com/elixir-lang/elixir/blob/master/lib/elixir/lib/map.ex#L330 
> > 
> > On Saturday, June 18, 2016 at 4:49:04 PM UTC-4, Filip Haglund wrote: 
> >> 
> >> Here's another implementation, using Enum.reduce, without an 
> intermediate 
> >> list: 
> >> 
> >> def map_filter_values(map, func) do 
> >>   Enum.reduce map, %{}, fn {key, val}, acc -> 
> >> if func.(val) do 
> >>   Map.put(acc, key, val) 
> >> else 
> >>   acc 
> >> end 
> >>   end 
> >> end 
> >> 
> >> 
> >> On Saturday, June 18, 2016 at 6:27:07 PM UTC+2, Filip Haglund wrote: 
> >>> 
> >>> I wish there was a Map.filter_values function that would filter on 
> keys 
> >>> or values, but leave the other one intact. This seems like something 
> that 
> >>> should be in the standard library. 
> >>> 
> >>> Example implementation of a Map.filter_values that would filter a map 
> >>> based on its values, leaving the keys intact: 
> >>> 
> >>> @doc """ 
> >>> Filter map based on its values, leaving the corresponding keys intact. 
> >>> """ 
> >>> @spec map_filter_values(Map.t, (any -> boolean)) :: Map.t 
> >>> def map_filter_values(map, func) do 
> >>>   map |> Enum.filter(fn {_, val} -> func.(val) end) |> Map.new 
> >>> end 
> >>> 
> >>> 
> >>> 
> >>> A corresponding Map.filter_keys would also be nice. 
> > 
> > -- 
> > 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/58c89485-0334-45ca-95f9-2a519060fc41%40googlegroups.com.
>  
>
> > 
> > For more options, visit https://groups.google.com/d/optout. 
>

-- 
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/1a84ccf3-6565-4871-8eec-9f7b3e89be45%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:5918] Re: Proposal: Map.filter_values and Map.filter_keys

2016-06-18 Thread Ben Wilson
Well I tried to reply but my email was deleted.

Long story short, successive Map.put calls are actually inferior to walking 
intermediary lists and building a new map at the end. You can read more 
about it here: https://github.com/elixir-lang/elixir/pull/4415

You'll note that Map.take is actually built in just that 
way: 
https://github.com/elixir-lang/elixir/blob/master/lib/elixir/lib/map.ex#L330

On Saturday, June 18, 2016 at 4:49:04 PM UTC-4, Filip Haglund wrote:
>
> Here's another implementation, using Enum.reduce, without an intermediate 
> list: 
>
> def map_filter_values(map, func) do
>   Enum.reduce map, %{}, fn {key, val}, acc ->
> if func.(val) do
>   Map.put(acc, key, val)
> else
>   acc
> end
>   end
> end
>
>
> On Saturday, June 18, 2016 at 6:27:07 PM UTC+2, Filip Haglund wrote:
>>
>> I wish there was a Map.filter_values function that would filter on keys 
>> or values, but leave the other one intact. This seems like something that 
>> should be in the standard library.
>>
>> Example implementation of a Map.filter_values that would filter a map 
>> based on its values, leaving the keys intact:
>>
>> @doc """
>> Filter map based on its values, leaving the corresponding keys intact.
>> """
>> @spec map_filter_values(Map.t, (any -> boolean)) :: Map.t
>> def map_filter_values(map, func) do
>>   map |> Enum.filter(fn {_, val} -> func.(val) end) |> Map.new
>> end
>>
>>
>>
>> A corresponding Map.filter_keys would also be nice.
>>
>

-- 
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/58c89485-0334-45ca-95f9-2a519060fc41%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:5915] Re: Proposal: Map.filter_values and Map.filter_keys

2016-06-18 Thread Ben Wilson
Your example implementation shows why this isn't really necessary. Moreover 
it doesn't compose well. Consider:

map
|> Enum.filter(fn {k, v} -> key_filter(k) && value_filter(v) end)
|> Map.new

vs

map
|> Map.filter_keys(key_filter)
|> Map.filter_values(value_filter)

In the latter it starts as a map, becomes a list, becomes a map again, then 
becomes a list, then becomes a map again.

There are a common set of operations which make sense for both lists, maps, 
streams, and other user made datastructures. Those common operations have 
been extracted into the Enum module based on the Enumerable protocol, and 
thats where they belong.

On Saturday, June 18, 2016 at 12:27:07 PM UTC-4, Filip Haglund wrote:
>
> I wish there was a Map.filter_values function that would filter on keys or 
> values, but leave the other one intact. This seems like something that 
> should be in the standard library.
>
> Example implementation of a Map.filter_values that would filter a map 
> based on its values, leaving the keys intact:
>
> @doc """
> Filter map based on its values, leaving the corresponding keys intact.
> """
> @spec map_filter_values(Map.t, (any -> boolean)) :: Map.t
> def map_filter_values(map, func) do
>   map |> Enum.filter(fn {_, val} -> func.(val) end) |> Map.new
> end
>
>
>
> A corresponding Map.filter_keys would also be nice.
>

-- 
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/733241e6-7490-4093-af3f-3825eba79c7b%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:5871] Re: Test grouping and named setups

2016-05-27 Thread Ben Wilson
I imagine the behaviour of assert and refute aren't going to change, as 
that'd be a breaking change. assert foo() == false is pretty clear as a 
work around though.

On Friday, May 27, 2016 at 4:23:50 PM UTC-4, Sergii Boiko wrote:
>
> Maybe a little bit offtopic, but my main issue with ExUnit is that assert 
> and refute match on truthiness and falsiness instead of strict true/false 
> match.
> First run into it when my test suddenly passed on empty function, because 
> it expected false, but refute accepts nil as well.
>
> The same issue was with Rspec 2, but they fixed it in RSpec 3. Maybe it's 
> possible to address it with some special option?
>
> On Friday, May 27, 2016 at 6:18:30 PM UTC+2, José Valim wrote:
>>
>> Hi everyone,
>>
>> There are two recurrent complaints about ExUnit when writing tests:
>>
>> 1. It does not support grouping
>> 2. It does not allow developers to name nor compose setup
>>
>> The only way in ExUnit to declare some code as part of a setup is by 
>> declaring a setup block and calling the function inside the block, like 
>> this:
>>
>> setup context do
>>
>>   {:ok, login_as(context)}
>>
>> end
>>
>>
>> I would like to propose improvements for those two issues. I will first 
>> write a proposal including code samples and then we can discuss naming and 
>> implementation details.
>>
>> ## Groups and named setups
>>
>> The idea is to introduce the group/2 macro and allow atoms to be given to 
>> setup:
>>
>> defmodule StringTest do
>>
>>   use ExUnit.Case, async: true
>>
>>   group "String.capitalize/2" do
>>
>> setup :set_test_string
>>
>> test "capitalizes the first letter", context do
>>
>>   assert "T" <> _ = context.test_string
>>
>> end
>>
>>   end
>>
>>
>>   group "String.bar/2" do
>>
>> setup context do
>>
>>   # Regular setups are not going anywhere and will still work
>>
>>   # You may return :ok | keyword | map
>>
>> end
>>
>> test "..." do ...
>>
>>   end
>>
>>   def set_test_string(_context) do
>>
>> %{test_string: "test_string"}
>>
>>   end
>>
>> end
>>
>>
>> By using groups, we can now better organize the tests and named setups 
>> allow us to easily share setup logic between groups without relying on 
>> nesting.
>>
>> Internally, we can consider "setup :some_atom" to be equivalent to:
>>
>> setup context, do: context |> some_atom()
>>
>>
>> The group/2 macro will also store the group tag in the test. For example, 
>> you will be able to:
>>
>> mix test --only group:"String.capitalize/2"
>>
>>
>> Setups defined in group/2 will only apply to the group. We will also 
>> support @grouptag to set some tags specific to the current group. setup_all 
>> cannot be called inside the group (as setup_all is always per test case). 
>> We won't allow group calls to be nested (we want developers to compose at 
>> the function level and not on nesting/hierarchies).
>>
>> ## Naming
>>
>> There is one big open question which is: is "group" a good name? I am 
>> personally not a fan. group works fine for grouping at the unit test level 
>> but it does not read nicely when you want to group based on a condition 
>> (for example, group "when name is an atom").
>>
>> Here are some alternatives: context, testing, group, describe, scenario, 
>> having, etc. I recommend everyone to actually try to write some 
>> pseudo-groups in their tests and see what reads nicely. I would love your 
>> feedback on what you think works nicely. Please include examples. :)
>>
>> One of my favorite picks is context but we already use context to mean 
>> the data that goes through setup and tests.
>>
>> ## Feedback
>>
>> Please give us feedback on this proposal. Those features are mostly 
>> straight-forward to implement, the most important aspects are the semantics.
>>
>> Thank you!
>>
>> *José Valim*
>> www.plataformatec.com.br
>> Skype: jv.ptec
>> Founder and Director of R&D
>>
>

-- 
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/6e41ef0d-f0fd-4d93-ae75-9d6bb3374ccb%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:5856] Re: Wrapping erlang modules with notoriously bad error messages

2016-05-26 Thread Ben Wilson
I chatted briefly with Jose and James about this, and it seems we're 
between a rock and a hard place a bit.

The issue is that erlang itself doesn't really have much by way of error 
messages. In the case of :ets for example it's literally just `:badarg`. 
What's worse is that in the case of :ets people pretty frequently try to 
catch specifically the `:badarg` value, so any changes would be breaking 
and seriously so.

:crypto is a little better because it's relatively rare to catch crypto 
errors, so we could at least return stuff like {:badarg, Key} or something, 
but the situation isn't great.

On Thursday, May 26, 2016 at 11:11:16 AM UTC-4, Myron Marston wrote:
>
> Maybe we could submit PRs to Erlang/OTP itself to improve the error 
> messages.  That way, it helps Erlang developers and helps us :).
>
> Myron
>
> On Thursday, May 26, 2016 at 4:53:55 AM UTC-7, Ben Wilson wrote:
>>
>> Well on further reflection my implementation id isn't gonna work easily. 
>> The basic idea with Ets specifically was to have a struct that included the 
>> various options used and to use that info to return better error messages 
>> in the event an error was raised. My thought was that that would only be 
>> done on error, so that it didn't incur much overhead in the happy path. 
>> This fails with just passing in a name though obviously so that won't work. 
>> Possibly there's some :ets debugging functions that could be used, I'll 
>> look into it more if there's interest.
>>
>> Crypto is easier. We know that keys have to be a certain byte width for 
>> example, so we just bake those checks into the elixir side and call out to 
>> `:crypto` if it's ok, otherwise return a useful error message.
>>
>> Thoughts?
>>
>> - Ben
>>
>> On Thursday, May 26, 2016 at 7:49:31 AM UTC-4, Ben Wilson wrote:
>>>
>>> I hit post too early, please hold...
>>>
>>> On Thursday, May 26, 2016 at 7:49:20 AM UTC-4, Ben Wilson wrote:
>>>>
>>>> Hey folks!
>>>>
>>>> I was prompted down this mode of thinking after answering some 
>>>> questions related to why `:ets` was returning argument error. Turns out 
>>>> they hadn't included the `[:named_table]` option. However the error 
>>>> message 
>>>> gave them exactly zero help when it comes to figuring out what is wrong.
>>>>
>>>> `:crypto` is another good example where any number of things can go 
>>>> wrong, and all will result in the same generic argument error.
>>>>
>>>> There's really two questions here:
>>>>
>>>> 1) Is it worth wrapping something like :ets or :crypto with an elixir 
>>>> module that could improve error messages?
>>>>
>>>> 2) Does this particular implementation idea I have sound reasonable?
>>>>
>>>> I split it up this way of course because while #2 may be a bad idea, I 
>>>> don't want rejection of #2 to imply rejection of #1.
>>>>
>>>>
>>>> ## Implementation notion.
>>>>
>>>> By way of example, let's tackle that :ets problem
>>>>
>>>> Ets.new returns %Ets{opts: [:named_table], ets_id: 123987}
>>>>
>>>> defmodule Ets do
>>>>
>>>> end
>>>>
>>>

-- 
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/719c979e-d8cd-4701-9752-e24f5cffb441%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:5849] Re: Wrapping erlang modules with notoriously bad error messages

2016-05-26 Thread Ben Wilson
Well on further reflection my implementation id isn't gonna work easily. 
The basic idea with Ets specifically was to have a struct that included the 
various options used and to use that info to return better error messages 
in the event an error was raised. My thought was that that would only be 
done on error, so that it didn't incur much overhead in the happy path. 
This fails with just passing in a name though obviously so that won't work. 
Possibly there's some :ets debugging functions that could be used, I'll 
look into it more if there's interest.

Crypto is easier. We know that keys have to be a certain byte width for 
example, so we just bake those checks into the elixir side and call out to 
`:crypto` if it's ok, otherwise return a useful error message.

Thoughts?

- Ben

On Thursday, May 26, 2016 at 7:49:31 AM UTC-4, Ben Wilson wrote:
>
> I hit post too early, please hold...
>
> On Thursday, May 26, 2016 at 7:49:20 AM UTC-4, Ben Wilson wrote:
>>
>> Hey folks!
>>
>> I was prompted down this mode of thinking after answering some questions 
>> related to why `:ets` was returning argument error. Turns out they hadn't 
>> included the `[:named_table]` option. However the error message gave them 
>> exactly zero help when it comes to figuring out what is wrong.
>>
>> `:crypto` is another good example where any number of things can go 
>> wrong, and all will result in the same generic argument error.
>>
>> There's really two questions here:
>>
>> 1) Is it worth wrapping something like :ets or :crypto with an elixir 
>> module that could improve error messages?
>>
>> 2) Does this particular implementation idea I have sound reasonable?
>>
>> I split it up this way of course because while #2 may be a bad idea, I 
>> don't want rejection of #2 to imply rejection of #1.
>>
>>
>> ## Implementation notion.
>>
>> By way of example, let's tackle that :ets problem
>>
>> Ets.new returns %Ets{opts: [:named_table], ets_id: 123987}
>>
>> defmodule Ets do
>>
>> end
>>
>

-- 
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/00a26074-1e7a-495d-a454-da61b187e12e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:5847] Wrapping erlang modules with notoriously bad error messages

2016-05-26 Thread Ben Wilson
Hey folks!

I was prompted down this mode of thinking after answering some questions 
related to why `:ets` was returning argument error. Turns out they hadn't 
included the `[:named_table]` option. However the error message gave them 
exactly zero help when it comes to figuring out what is wrong.

`:crypto` is another good example where any number of things can go wrong, 
and all will result in the same generic argument error.

There's really two questions here:

1) Is it worth wrapping something like :ets or :crypto with an elixir 
module that could improve error messages?

2) Does this particular implementation idea I have sound reasonable?

I split it up this way of course because while #2 may be a bad idea, I 
don't want rejection of #2 to imply rejection of #1.


## Implementation notion.

By way of example, let's tackle that :ets problem

Ets.new returns %Ets{opts: [:named_table], ets_id: 123987}

defmodule Ets do

end

-- 
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/72232708-7317-4e83-b0b5-2c0aba53684c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:5848] Re: Wrapping erlang modules with notoriously bad error messages

2016-05-26 Thread Ben Wilson
I hit post too early, please hold...

On Thursday, May 26, 2016 at 7:49:20 AM UTC-4, Ben Wilson wrote:
>
> Hey folks!
>
> I was prompted down this mode of thinking after answering some questions 
> related to why `:ets` was returning argument error. Turns out they hadn't 
> included the `[:named_table]` option. However the error message gave them 
> exactly zero help when it comes to figuring out what is wrong.
>
> `:crypto` is another good example where any number of things can go wrong, 
> and all will result in the same generic argument error.
>
> There's really two questions here:
>
> 1) Is it worth wrapping something like :ets or :crypto with an elixir 
> module that could improve error messages?
>
> 2) Does this particular implementation idea I have sound reasonable?
>
> I split it up this way of course because while #2 may be a bad idea, I 
> don't want rejection of #2 to imply rejection of #1.
>
>
> ## Implementation notion.
>
> By way of example, let's tackle that :ets problem
>
> Ets.new returns %Ets{opts: [:named_table], ets_id: 123987}
>
> defmodule Ets do
>
> end
>

-- 
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/0bb576e2-a871-42f1-bbad-7be8f5f60a34%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:5798] Re: Add ~w(str0 str1 str2) equivalent for symbols.

2016-05-24 Thread Ben Wilson
You'll find documentation about what modifiers are supported in the 
docs http://elixir-lang.org/docs/master/elixir/Kernel.html#sigil_w/2

Definitely a good idea, that's why we can do it :)

On Tuesday, May 24, 2016 at 6:21:51 PM UTC-4, Ben Wilson wrote:
>
> ~w(foo bar baz)a creates a list of atoms.
>
> On Tuesday, May 24, 2016 at 6:13:02 PM UTC-4, yuy...@gmail.com wrote:
>>
>> When using ecto-2.0, required fields must be a list of symbols therefore 
>> the code will look like this:
>>
>> fields ~w(email password encrypted_password)
>> required [:email, password]
>>
>>
>> And in my humble opinion, it would be better if we can write it like:
>>
>> fields ~w(email password encrypted_password)
>> required ~s(email password)
>>
>>
>> I know ~s is used for string right now, but I believe it's better if we 
>> can follow the Ruby's convention where s is used for symbols and w is 
>> q(quoted) is used for strings.
>>
>> Any thought?
>>
>

-- 
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/177b3403-5ec3-4e7b-b0b6-7a7a0259613e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elixir-core:5797] Re: Add ~w(str0 str1 str2) equivalent for symbols.

2016-05-24 Thread Ben Wilson
~w(foo bar baz)a creates a list of atoms.

On Tuesday, May 24, 2016 at 6:13:02 PM UTC-4, yuy...@gmail.com wrote:
>
> When using ecto-2.0, required fields must be a list of symbols therefore 
> the code will look like this:
>
> fields ~w(email password encrypted_password)
> required [:email, password]
>
>
> And in my humble opinion, it would be better if we can write it like:
>
> fields ~w(email password encrypted_password)
> required ~s(email password)
>
>
> I know ~s is used for string right now, but I believe it's better if we 
> can follow the Ruby's convention where s is used for symbols and w is 
> q(quoted) is used for strings.
>
> Any thought?
>

-- 
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/e48978ef-db93-4e0e-b49e-27ec8a596c54%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elixir-core:5698] Add boolean methods for different unicode character groups (String.alphanumeric?, etc)

2016-05-09 Thread Ben Wilson
http://nerves-project.org/ Enjoy :)

On Monday, May 9, 2016 at 12:36:45 PM UTC-4, Ed Wildgoose wrote:
>
> On 05/05/2016 17:44, w.m.w...@student.rug.nl  wrote: 
>
> > - when included in the stdlib, compiling/usin Elixir on embedded devices 
> becomes impossible because of the increased file size. 
>
> Head above the parapet, but I would be interested in using Elixir in 
> some embedded stuff. Object size and runtime size is important. I guess 
> I'm not really "embedded" as my linux image sizes are usually 10MB+ 
> (including kernel), but I still want to keep things small when I can.   
> Having the ability to strip down unicode support may be useful for some 
> requirements... 
>
> Thanks for consideration... 
>
> Ed W 
>
>
>
>

-- 
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/54e4211c-d41a-4418-9678-6c052dd4fddd%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.