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

2019-02-11 Thread Martin Svalin
Imho, given that a Map allows duplicate values, `inverse` is a poor fit for
the data structure as such. Map is also not the only key-value data
structure common in Elixir. Should there be a corresponding
Keyword.inverse/1? It would add the interesting twist that neither key or
value need to be unique.

A safely invertible map is a separate data structure, and can be provided
in hex packages. If a developer needs guarantees around uniqueness of
values, then a plain map is something that needs to be treated carefully.
In other cases, the content of the map is known (literal, perhaps), and a
straight up Map.new(for {k,v} <- map, do: {v,k}) is just fine.

I agree there are use cases for inverting a map, but I believe the use
cases are different enough that a Map.invert/1 risks having a confusing API
for duplicates. I think the proposal shows this. Better then to leave it to
the dev or to library maintainers.

I think functions in the data structure modules like Map, List, String etc
should work with _any_ value of that kind, not come with warnings to not
use them unless your data has these special properties.

my 2 cents. /Martin

On Sun, Feb 10, 2019 at 6:30 PM Glauber Campinho 
wrote:

> Sorry, to be more clear, if you have a map and invert the keys, but have
> an exception for arrays in the keys, it would possible the inverse of the
> inverse would be Identity. Then the strange thing is that sometimes you
> invert the keys, sometimes you split the keys.
>
> All of this seems very specific to the case that you are dealing with,
> people will want different behaviors for different cases.
>
> On Sun, Feb 10, 2019, 18:24 Glauber Campinho 
>> If the invert returns a list of values for duplicate values, the invert
>> of invert would not be the original value. That is a strange behavior in my
>> opinion.
>>
>> On Sun, Feb 10, 2019, 09:41 Justin Gamble >
>>> Hi Andrea,
>>>
>>>
>>> I think there are two questions:
>>>
>>> First question: what are use cases?
>>>
>>>
>>> Basically it is whenever the keys and values in a map have equal
>>> importance as being the reference.  Inverting a map allows you use a value
>>> to look up a key.
>>>
>>>
>>> The following are *use cases* for inverting a map, where it makes sense
>>> to do a lookup on the key & also to do a lookup on the value:
>>>
>>>
>>>
>>>-
>>>
>>>Phone Book.  You may have a name and want to lookup the phone
>>>number, or vice versa.  (idea taken from here
>>>
>>> 
>>>)
>>>-
>>>
>>>Converting between languages.  To map words/expressions between 2
>>>languages.
>>>-
>>>
>>>Encrypting/decrypting data
>>>-
>>>
>>>Capital city & State.  ("given this capital city, what is its
>>>state?", "given this state, what is its capital city?")
>>>-
>>>
>>>Sports team & school
>>>-
>>>
>>>Sports player name & player number
>>>-
>>>
>>>Countries & their final ranked position  (i.e. in Soccer World Cup)
>>>-
>>>
>>>Finally, to recap the motivation in the original proposal:
>>>Converting between English titles and record IDs for talking to APIs.  
>>> The
>>>same argument could be applied for talking to a database instead of an 
>>> API.
>>>-
>>>
>>>   For example, for a school application you many need to convert
>>>   between classroom_number & classroom_ID , or student_name & student_ID
>>>
>>>
>>> Here are examples from other programming languages showing that
>>> developers are commonly asking about this functionality.
>>>
>>> Ruby:
>>>
>>>-
>>>
>>>
>>>
>>> https://stackoverflow.com/questions/10989259/swapping-keys-and-values-in-a-hash?rq=1
>>>-
>>>
>>>
>>>
>>> https://stackoverflow.com/questions/29837790/inverting-a-hash-making-multiple-hash-keys-from-an-array
>>>
>>>
>>> Python:
>>>
>>>-
>>>
>>>
>>>
>>> https://stackoverflow.com/questions/483666/python-reverse-invert-a-mapping
>>>-
>>>
>>>
>>>
>>> https://stackoverflow.com/questions/44851342/reverse-a-dictionary-in-python
>>>-
>>>
>>>
>>>
>>> https://stackoverflow.com/questions/7304980/invert-keys-and-values-of-the-original-dictionary
>>>
>>>
>>> Perl:
>>>
>>>-
>>>
>>>
>>>
>>> https://stackoverflow.com/questions/6128970/inverting-a-hashs-key-and-values-in-perl
>>>-
>>>
>>>
>>>
>>> https://stackoverflow.com/questions/11902558/how-do-i-invert-a-hash-with-complex-values
>>>
>>>
>>>
>>> Java:
>>>
>>>-
>>>
>>>
>>>
>>> https://stackoverflow.com/questions/20412354/reverse-hashmap-keys-and-values-in-java
>>>-
>>>
>>>https://stackoverflow.com/questions/9783020/bidirectional-map
>>>
>>>
>>>
>>> One reason to implement Map.invert() now is to avoid further people
>>> asking about it in the future. ;)
>>>
>>> Second question: is the function too small to add to the library?
>>>
>>> I now think the initial code I proposed is inadequate.  The Map.new/2
>>> solution is also inadequate. A Map 

Re: [elixir-core:8439] [Proposal] Shorthand to filter tests by multiple line numbers

2019-01-09 Thread Martin Svalin
Hm. I'll chip in with an opinion based on surprises I got experimenting a
bit with the mix test task.

If I wanted to run tests across multiple files identified by line numbers,
I would naively write `mix test test/some_test.exs:15
test/some_test.exs:20`.

`mix test test/some_test.exs` will run all tests of a single file.  
`mix test test/some_test.exs test/another_test.exs` will run all tests of
both files. 
`mix test test/some_test.exs:15` will run the test located at line 15 for
that file. 

`mix test test/some_test.exs test/another_test.exs:20` will run all tests
in some_test.exs, but not the test at line 20 in another_test.exs. 樂
`mix test test/some_test.exs:15 test/another_test.exs` will run all tests
in another_test.exs, but not the test at line 15 in some_test.exs 樂

In both cases, my expectation was to run all tests of one file, and the
test at the specific line for the other file.

`mix test test/some_test.exs:15 test/another_test:20` will exit with an
error:
"Paths given to `mix test` did not match any directory/file:
test/some_test.exs:15, test/another_test.exs:20"  

My expectation was that two tests would have been run, the one at line 15
in some_test.exs, and at line 20 in another_test.exs.

Do people agree that this naive expectation is an intuitive one? (I didn't
really know any of the internals of the test runner.) Or would other people
have other intuitions?

For running multiple tests in a single file identified by line numbers, I'd
support `mix test test/some_test.exs:15:20:35`.
I'd also expect to be able to run `mix test test/some_test.exs:15:20:35
test/another_test.exs:40:75:120`.

The question of shorthand for multiple lines within a single file is of
course separate from that of running individual tests across multiple
files. Simply commenting as the multi-file issue was brought up.

On Wed, Jan 9, 2019 at 4:56 PM Devon Estes  wrote:

> `mix test --only line:74 --only line:92
> test/potion_web/plugs/persist_request_plug_test.exs` does work, but don't
> you think it's a little confusing to allow `--only` more than once?
>
> I'm cool with the `mix test
> test/potion_web/plugs/persist_request_plug_test.exs:92:94:102` syntax.
> Whatever syntax is chosen doesn't matter all that much to me, acutally.
>
> I've personally never wanted to run tests in more than one file, but I can
> imagine that someone might (i.e. running some unit tests & integration
> tests together).
>
> On Wednesday, January 9, 2019 at 12:44:07 PM UTC+1, Amos King wrote:
>>
>> The syntax that José proposed is common to other command line tools so I
>> vote for it.
>>
>> I have wanted to do more than one file. As a user I’m not at all
>> concerned with the verbosity of the parsed version. If it isn’t a big
>> impact on performance. Some setups can be large, and starting of
>> applications. I’d rather save the time there and not have to chain command
>> line calls. Chaining command line calls also has the added issue of one
>> command has a failure and the rest don’t run.
>>
>> Amos King
>> Binary Noggin
>>
>> On Jan 9, 2019, at 04:46, Sven Gehring  wrote:
>>
>> I'd personally prefer the syntax proposed by José.
>>
>> Also, I would argue that allowing for multiple files introduces quite a
>> bit of unnecessary complexity.
>>
>> I never had the need to run only specific tests in multiple files but I
>> think if it is really necessary for
>> someone, you can always still chain the commands (ie. mix test ... && mix
>> test ...) which is not ideal
>> because you do the setup/teardown twice but I think it would work to
>> cover that edge case
>>
>> Sven
>>
>> On Wed, 9 Jan 2019 at 11:18 José Valim 
>> wrote:
>>
>>> *Stream of thoughts below.*
>>>
>>> Can you use only instead?
>>>
>>> mix test --only line:74 --only line:92
>>> test/potion_web/plugs/persist_request_plug_test.exs
>>>
>>>
>>> My only concern with your feature proposal is that it may lead to
>>> wanting to run multiple tests across multiple files and that's a trickier
>>> problem. One option would be change our line filter to be something like
>>> file+line. In a way that:
>>>
>>> mix test test/potion_web/plugs/persist_request_plug_test.exs:92
>>>
>>>
>>> becomes:
>>>
>>> Including tags: [location:
>>> {"test/potion_web/plugs/persist_request_plug_test.exs", 92}]
>>>
>>>
>>> but that's quite more verbose. Thoughts?
>>>
>>> However, if we decide we don't need to support multiple files, then I
>>> would do:
>>>
>>> mix test test/potion_web/plugs/persist_request_plug_test.exs:92:94:102
>>>
>>>
>>> *José Valim*
>>> www.plataformatec.com.br
>>> Skype: jv.ptec
>>> Founder and Director of R
>>>
>>>
>>> On Wed, Jan 9, 2019 at 11:00 AM Devon Estes  wrote:
>>>
 Currently, if I want to run only a single test by line number, I can
 easily do:

 mix test test/potion_web/plugs/persist_request_plug_test.exs:92

 This is parsed in ExUnit as:

 Including tags: [line: "92"]
 Excluding tags: [:test]

 But if I want to only 

Re: [elixir-core:8024] Re: [Proposal] Map.take!/2

2018-05-25 Thread Martin Svalin
(edited to have the year fail instead of the month, but didn't edit enough…
month: 5, 2017 != 2018… you get the gist. Sorry)

fre 25 maj 2018 kl 10:59 skrev Martin Svalin <martin.sva...@gmail.com>:

> So essentially you are concerned with this scenario?
>
> ```elixir
> actual = Map.take(DateTime.utc_now, [:yaer, :month]) # note misspelling
> expected = Map.take(%{year: 2017, month: 6, day: 1}, [:yaer, :month]) #
> same misspelling
> assert actual == expected  # passes even though we're in 2018
> ```
>
> I would write that as
>
> ```elixir
> assert %{yaer: 2018, month: 6} = DateTime.utc_now
> ```
>
> Which would fail for the correct reason: the misspelling. Fixing this
> would reveal the test failure that 5 != 6.
> You'd have similar failures if your tests were correctly spelled, but your
> data was misspelled or missing keys.
>
> I'm not opposed to the idea of a `Map.take!` that raises KeyError. I don't
> have a use case handy, though.
>
> - Martin
>
> tors 24 maj 2018 kl 23:57 skrev Tallys Martins <tallysmart...@gmail.com>:
>
>> Well, this does not suites for my cases because I actually have object
>> maps like %Measurement{}. The problem comes when I need to pattern match
>> its attributes like id and others. Let me give you some context, but maybe
>> I am going through the wrong solution, though.
>>
>> This code:
>>
>> assert expected_measurement = measurement
>>
>> would fail because association attributes in measurement are not loaded
>> Ecto.Association.NotLoaded (and they are supposed to)
>>
>> So I selected the ones that I care, not simple the id, but to resume:
>>
>> assert %Measurement{id: ^expected_measurement.id} = measurement
>>
>> And this raise an error: cannot invoke remote function
>> expected_measurement.id/0 inside match
>>
>> So I decided to use Map.take/2 on both maps checking a list of attributes
>> that I think that matters the most. The problem is that if one comes with
>> an attribute that does not exists, the tests will equally pass, so I
>> thought it would be good to have a Map.take!/2 function to help on that.
>>
>> Em qui, 24 de mai de 2018 às 17:46, Peter Hamilton <
>> peterghamil...@gmail.com> escreveu:
>>
>>> Thanks for searching for an old thread rather than making a new one!
>>>
>>> > I pattern match just a few keys of my map objects
>>>
>>> Would just doing a direct pattern match work here?
>>>
>>> %{foo: foo, bar: bar} = my_map
>>>
>>> That would fail if foo or bar was missing in my_map.
>>>
>>> On Thu, May 24, 2018 at 1:11 PM Tallys Martins <tallysmart...@gmail.com>
>>> wrote:
>>>
>>>> Hi!
>>>>
>>>> I could not find a final reply for this thread, here nor at Github, so
>>>> I am here to ask and argue why this would be a useful function.
>>>>
>>>> I am writing some tests where I pattern match just a few keys of my map
>>>> objects using Map.take. Developers could type invalid keys and the tests
>>>> would still pass.
>>>> If you are open to receive an implementation for this I can work on it
>>>> and give my first piece of contribution.
>>>>
>>>> Sorry for reviving something deep in the past if its already solved.
>>>>
>>>> Warm Regards,
>>>> Tallys Martins
>>>>
>>>>
>>>> Em quarta-feira, 30 de novembro de 2016 21:25:18 UTC-2, Aaron Tinio
>>>> escreveu:
>>>>>
>>>>> Map.take!(map, keys)
>>>>>
>>>>> Same as Map.take/2 but raises a KeyError when one of the keys doesn't
>>>>> exist.
>>>>>
>>>> --
>>>> 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/6c898b72-6626-4738-8331-cdee13cff251%40googlegroups.com
>>>> <https://groups.google.com/d/msgid/elixir-lang-core/6c898b72-6626-4738-8331-cdee13cff251%40googlegroups.com?utm_medium=email_source=footer>
>>>> .
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>>

Re: [elixir-core:8024] Re: [Proposal] Map.take!/2

2018-05-25 Thread Martin Svalin
So essentially you are concerned with this scenario?

```elixir
actual = Map.take(DateTime.utc_now, [:yaer, :month]) # note misspelling
expected = Map.take(%{year: 2017, month: 6, day: 1}, [:yaer, :month]) #
same misspelling
assert actual == expected  # passes even though we're in 2018
```

I would write that as

```elixir
assert %{yaer: 2018, month: 6} = DateTime.utc_now
```

Which would fail for the correct reason: the misspelling. Fixing this would
reveal the test failure that 5 != 6.
You'd have similar failures if your tests were correctly spelled, but your
data was misspelled or missing keys.

I'm not opposed to the idea of a `Map.take!` that raises KeyError. I don't
have a use case handy, though.

- Martin

tors 24 maj 2018 kl 23:57 skrev Tallys Martins :

> Well, this does not suites for my cases because I actually have object
> maps like %Measurement{}. The problem comes when I need to pattern match
> its attributes like id and others. Let me give you some context, but maybe
> I am going through the wrong solution, though.
>
> This code:
>
> assert expected_measurement = measurement
>
> would fail because association attributes in measurement are not loaded
> Ecto.Association.NotLoaded (and they are supposed to)
>
> So I selected the ones that I care, not simple the id, but to resume:
>
> assert %Measurement{id: ^expected_measurement.id} = measurement
>
> And this raise an error: cannot invoke remote function
> expected_measurement.id/0 inside match
>
> So I decided to use Map.take/2 on both maps checking a list of attributes
> that I think that matters the most. The problem is that if one comes with
> an attribute that does not exists, the tests will equally pass, so I
> thought it would be good to have a Map.take!/2 function to help on that.
>
> Em qui, 24 de mai de 2018 às 17:46, Peter Hamilton <
> peterghamil...@gmail.com> escreveu:
>
>> Thanks for searching for an old thread rather than making a new one!
>>
>> > I pattern match just a few keys of my map objects
>>
>> Would just doing a direct pattern match work here?
>>
>> %{foo: foo, bar: bar} = my_map
>>
>> That would fail if foo or bar was missing in my_map.
>>
>> On Thu, May 24, 2018 at 1:11 PM Tallys Martins 
>> wrote:
>>
>>> Hi!
>>>
>>> I could not find a final reply for this thread, here nor at Github, so I
>>> am here to ask and argue why this would be a useful function.
>>>
>>> I am writing some tests where I pattern match just a few keys of my map
>>> objects using Map.take. Developers could type invalid keys and the tests
>>> would still pass.
>>> If you are open to receive an implementation for this I can work on it
>>> and give my first piece of contribution.
>>>
>>> Sorry for reviving something deep in the past if its already solved.
>>>
>>> Warm Regards,
>>> Tallys Martins
>>>
>>>
>>> Em quarta-feira, 30 de novembro de 2016 21:25:18 UTC-2, Aaron Tinio
>>> escreveu:

 Map.take!(map, keys)

 Same as Map.take/2 but raises a KeyError when one of the keys doesn't
 exist.

>>> --
>>> 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/6c898b72-6626-4738-8331-cdee13cff251%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/CAOMhEnwKOfH4scFO7JKK3nBqZUKj_CP9mV0km6%3D2gw%3D3UiNGQg%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/CAHtu5s8pHEqQEnYcNAXbvSnRRXeciXrQSwmk1OoXZ%2Bn1PyYnUA%40mail.gmail.com
> 
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You 

Re: [elixir-core:7924] Enhancement request: parse character offsets for AST node

2018-02-28 Thread Martin Svalin
I think you can reformat a part of the AST.

iex> some_ast_fragment = quote do [h|t] end
iex> some_ast_fragment |> Macro.to_string() |> Code.format_string! |>
Enum.join
"[h | t]"

Not sure if this would work for you. And the round-trip to a string might
not be necessary; I haven't had more than a cursory look at Code.Formatter.

- Martin

tis 27 feb. 2018 kl 12:32 skrev Serge Smetana :

> Hi,
>
> Sounds reasonable but may not work as good. This may change a lot of user
> formatted code and produce extra diffs in tests. If we could only reformat
> a part of the AST (one function call in our case) this would be ideal.
>
> Thanks,
> Serge.
>
> On Monday, February 26, 2018 at 2:31:01 PM UTC+2, Louis Pop wrote:
>
>> Hi there
>>
>> Given we have the formatter now I would be tempted to avoid editing
>> strings and instead update the AST of the file, render that to a string,
>> format it and write it back to the file. Would be more reliable.
>>
>> Cheers,
>> Louis
>>
>> On Mon, 26 Feb 2018, 12:11 Serge Smetana,  wrote:
>>
> Hi,
>>>
>>> I would like Elixir AST nodes to include begin and end parse character
>>> offsets.
>>> This would make it easier to write refactoring tools that modify parts of
>>> Elixir source files.
>>>
>>> Usecase:
>>>
>>> We have a library https://github.com/assert-value/assert_value_elixir
>>> that is
>>> able to create and update expected values in tests. For example, given
>>> the
>>> following:
>>>
>>> assert_value 2 + 2 == 2 + 3
>>>
>>> our code will find the location of `2 + 3` and replace it with `4`:
>>>
>>> assert_value 2 + 2 == 4
>>>
>>> Today determining the location of `2 + 3` in the source file is
>>> difficult.  For
>>> now, we use a custom-made parser which processes code char by char until
>>> it gets
>>> value matching AST:
>>>
>>> https://github.com/assert-value/assert_value_elixir/blob/master/lib/assert_value/parser.ex
>>> But if we had the parse offsets it would be much easier.
>>>
>>> Proposed interface:
>>>
>>> Probably need two sets of offsets, exclusive and inclusive of children.
>>> For
>>> each probably best to store beginning offset and length. Will need
>>> reasonable
>>> handling for parentheses and other tokens that do not make it into AST.
>>>
>>> Existing implementation:
>>>
>>> Elixir AST nodes do have useful info on this already. We use the "line:"
>>> which
>>> is very helpful. We don't use "column:", it did not seem useful given our
>>> implementation.  We may be missing something obvious here.
>>>
>>> Details:
>>>
>>> In Elixir 1.6 compiled code AST has only function line number in meta.
>>> Even
>>> "columns: true" in Code.string_to_quoted gives only function starting
>>> column
>>> without information about arguments.
>>>
>>> Consider the following code:
>>>
>>> Code.string_to_quoted!("(41.00 == 42.)", columns: true)
>>> #=> {:==, [line: 1, column: 8], [41.0, 42.0]}
>>>
>>> From the AST you don't know where to find 41.00 and 42. in a code.
>>> Column information does not help. AST values of 41.0 and 42.0 don't have
>>> information about how original values were formatted.
>>>
>>> Thanks,
>>> Serge
>>>
>>> --
>>> 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/4dbc37cc-6630-4989-acc0-c4acfd719a5b%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/644251b6-8b27-4836-98a3-a9feddcc29ba%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/CAAHw6CJR5Vmf9woaU4tNJk_fJx80Tzi0gw9dgSPc%2BQK0Gu1vBw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elixir-core:7753] Proposal: Allow IO.inspect to accept a function as argument

2018-01-15 Thread Martin Svalin
`map` would have the connotation of applying a function to all elements of
a collection. `apply` would more directly have the connotation of running a
function with some arguments.

`IO.inspect(value, apply: /1)`

I like the idea of being able to narrow down what I'm inspecting during the
print-debugging workflow I inevitably regress to. `nested_structure |>
IO.inspect(apply: & get_in(&1, [:foo, :bar, :baz]))`. Thumbs up for the
idea.

mån 15 jan. 2018 kl 17:31 skrev Marcus Gartner :

> Doh! I should have realized the issue with executing the function passed.
>
> I like the idea of a transform option that can be passed.
>
> IO.map makes sense in my example, but wouldn't make sense to me if the
> pipeline wasn't dealing with an enumerable, and it would be nice if this
> feature was general enough to work idiomatically with any possible values.
>
> On Sat, Jan 13, 2018 at 7:38 PM OvermindDL1  wrote:
>
>> Or call it `map` as it's shorter and perfectly descriptive.  I've made a
>> few variants of this myself and I'd love it built into IO.inspect.
>>
>> On Jan 12, 2018 16:31, "Greg Vaughn"  wrote:
>>
>>> I like the original idea and would like to suggest another approach.
>>> What if there were an additional Inspect.Opts of :transform? It then would
>>> enable this sort of thing:
>>>
>>> ["thing1", "thing2"]
>>> |> generate_more_things()
>>> |> IO.inspect(transform: /1)
>>> |> do_something_with_things()
>>>
>>> -Greg Vaughn
>>>
>>> > On Jan 12, 2018, at 5:18 PM, José Valim  wrote:
>>> >
>>> > Thanks for the proposal!
>>> >
>>> > Unfortunately that would make us unable to inspect functions
>>> themselves, which is a valid argument to IO.inspect after all.
>>> >
>>> > Imagine the confusion of trying to inspect a pipeline that may emit an
>>> anonymous function only to find it is being executed instead.
>>> >
>>> >
>>> >
>>> > José Valim
>>> > www.plataformatec.com.br
>>> > Founder and Director of R
>>> >
>>> > On Fri, Jan 12, 2018 at 10:59 PM,  wrote:
>>> > I often find myself wanting to inspect things in the middle of a chain
>>> of pipes, but I don’t always want to inspect the return values as-is.
>>> Sometimes I want to inspect sub-attributes or call functions on the return
>>> values to inspect them.
>>> >
>>> > For example, imagine the contrived pipeline below.
>>> >
>>> > ["thing1", "thing2"]
>>> > |> generate_more_things()
>>> > |> do_something_with_things()
>>> >
>>> > If I want to know the length of the list returned by
>>> generate_more_things/1, I would do this:
>>> >
>>> > ["thing1", "thing2"]
>>> > |> generate_more_things()
>>> > |> (fn things ->
>>> >   things |> length() |> IO.inspect()
>>> >   things
>>> > end).()
>>> > |> do_something_with_things()
>>> >
>>> > If IO.inspect can take a function as an argument, print the inspection
>>> of the result of calling that function, but still return the un-altered
>>> input, I could do this:
>>> >
>>> > ["thing1", "thing2"]
>>> > |> generate_more_things()
>>> > |> IO.inspect(fn things -> length(things) end)
>>> > |> do_something_with_things()
>>> >
>>> > Or even:
>>> >
>>> > ["thing1", "thing2"]
>>> > |> generate_more_things()
>>> > |> IO.inspect(/1)
>>> > |> do_something_with_things()
>>> >
>>> > I think this would aid during debugging and be a useful feature in the
>>> standard library. I'd love to implement and contribute on this, but I
>>> wanted to see if such a thing would be accepted before beginning work.
>>> >
>>> > Open 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-core+unsubscr...@googlegroups.com.
>>> > To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/elixir-lang-core/4e2bfad0-b745-4059-8736-996e641c7bb2%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/CAGnRm4KAvw%2BwWnh7d60%3DvKEkuLvWfyoh4XuM9rbuxz_CaLg9%3DA%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/6CF01F3F-5848-4E19-BCA1-9D256824D6E0%40gmail.com
>>> .
>>> For more 

Re: [elixir-core:7542] Is it possible to have an `is_module` function?

2017-10-16 Thread Martin Svalin
The closest thing we have is `Code.ensure_loaded/1`. If you don't check
that the module exists, you're basically just checking that the input is an
atom. And if you use ensure_loaded, you'll have a predicate function with
side effects. You'd also break the expectation of guard safety with the
`is_` prefix.

Would your `is_module/1` have different behaviour than `is_atom/1`? Would
it be true only of atoms of the form `:"Elixir.SomeModule"`? I'm not sure
it should, since `defmodule :random_atom` is valid.

Which is a long way of saying, I think you should use `is_atom`. Perhaps
with a line comment `# for modules`.


mån 16 okt. 2017 kl 20:02 skrev Devon Estes :

> We just encountered something that seemed kind of odd, so I wanted to pass
> it by the list to see if it could be a possible feature.
>
> In Benchee we want to accept either a module or a function as an argument
> to a function. We'll have different behavior depending on the type there
> (since we're expecting any module passed in to implement a certain
> behaviour). However, there's no check for `is_module`. We were thinking of
> using `is_atom` (see here:
> https://github.com/PragTob/benchee/pull/148/files#diff-e8ef07ff6be58cfaaaf6f03420fc53e7R75),
> but that seems sort of confusing to me. I know technically modules are
> atoms, but would it be possible to have an `is_module` function that can be
> used in guard clauses and elsewhere that would more accurately convey the
> sort of thing we're trying to do?
>
> --
> 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/8a823a05-3da0-4de8-b96c-273bd12297b8%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/CAAHw6CKCXb0Q67YMXFF0_fdcUaLvXWnAz5mLHEGFCZB%2BrU_J_Q%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elixir-core:7475] Re: Maybe Map.replace should lazily evaluate the new value, or introduce Map.replace_lazy?

2017-10-03 Thread Martin Svalin
I'm unclear what you want the proposed function to return when the key
isn't present. The map, untouched? I think that behaviour would be a
surprise to some. I like the explicitness of `Map.get_and_update/3`.

`Map.get_and_update(map, key, fn
  nil -> map
  n -> n + 1
end)`

-- 
- Martin

tis 3 okt. 2017 kl 20:40 skrev Ary Borenszweig :

> I saw it, but it's different from what I want. There are two versions:
> - get_and_update(map, key, fun): fun is called with the current value
> under key in map (*or nil if key is not present in map*) -> I don't want
> that nil, it will break my code
> - get_and_update!(map, key, fun): raises if there's no key
>
> I want something like this:
>
> ~~~
> Map.put_lazy(map, key, fun value -> value + 1 end)
> ~~~
>
> Here, the function is only invoked if key is present in map.
> `get_and_update` would invoke that function with `nil`.
>
>
>
> On Tuesday, October 3, 2017 at 3:00:43 PM UTC-3, Tallak Tveide wrote:
>>
>> https://hexdocs.pm/elixir/Map.html#get_and_update!/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/1164ddd8-de7d-4e0d-b140-63db6b6b6646%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/CAAHw6C%2BLeJdT2d%3DgRUaQNMehrKhuY8ARb1Q-Opxoti3UxpMw4g%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.