For anyone following this, this was already implemented :)

El martes, 18 de mayo de 2021 a las 10:32:28 UTC-3, i Dorgan escribió:

> Yes, the split is meant for the internal API. User API would remain 
> unchanged except for the addition of quoted_to_algebra and 
> string_to_quoted_with_comments to the Code module
>
> El martes, 18 de mayo de 2021 a las 10:03:26 UTC-3, José Valim escribió:
>
>> We don't need to add new modules to the user API but internally we can 
>> split them in whatever way we want. Splitting also depends on how large it 
>> is, but probably best to avoid adding it to the formatter since that's 
>> already 2k LOC.
>>
>>
>> On Tue, May 18, 2021 at 2:49 PM i Dorgan <[email protected]> wrote:
>>
>>> Hi all,
>>>
>>> Now that https://github.com/elixir-lang/elixir/pull/10986/ is merged I 
>>> was meaning to prepare a PR for the normalizing step. Would you prefer to 
>>> have that code in the Code.Formatter module, or in a separate 
>>> Code.Normalizer module? Personally I would prefer the latter, I think it 
>>> would make the code that does the actual formatting easier to follow.
>>>
>>> El domingo, 9 de mayo de 2021 a las 0:20:37 UTC-3, i Dorgan escribió:
>>>
>>>> I tried manual traversal and that made things so much easier, the 
>>>> literal? field is no longer needed. I made good progress on the conversion 
>>>> and I think I have covered most of the edge cases, judging from the tests 
>>>> I 
>>>> wrote: 
>>>> https://github.com/doorgan/formatter/blob/main/test/normalize_test.exs
>>>> The approach I took for testing was to run the formatter with both the 
>>>> AST generated internally by `Code.Formatter.to_algebra` and with the one 
>>>> I'm creating, as well as feeding the special AST to my normalizer to make 
>>>> sure literals don't get wrapped twice. I did not test the specific shapes 
>>>> the AST should have in most cases but the most basic ones, but it may be a 
>>>> good idea to do so.
>>>>
>>>> My next step would be to test it with comments, I expect them not land 
>>>> in the correct lines in every case because I'm making literals inherit the 
>>>> line number of their parents and heredocs lose delimiter information, but 
>>>> at the very least it the formatter should not break.
>>>>
>>>> If this works then I think I'd be in a good position to submit a PR, 
>>>> once a PR to expose the comments maps is submitted.
>>>> El sábado, 8 de mayo de 2021 a las 2:54:13 UTC-3, José Valim escribió:
>>>>
>>>>> > I had to add a literal? field to the literal blocks to distinguish 
>>>>> them from regular blocks and prevent the normalizer from recursing 
>>>>> infinitely.
>>>>>
>>>>> You can always traverse manually. The number of AST nodes are small 
>>>>> and it will give you more control. Alternatively, give postwalk a try, 
>>>>> since the block node you add on postwalk won't be traversed (IIRC).
>>>>>
>>>>> The approach looks good to me. Note for some of those, I would prefer 
>>>>> to push the fix to the formatter (for example, we can assume :delimiter 
>>>>> defaults to ~s"").
>>>>>
>>>>> On Sat, May 8, 2021 at 12:12 AM i Dorgan <[email protected]> wrote:
>>>>>
>>>>>> I'm currently experimenting on the second point you outlined
>>>>>>
>>>>>> I've uploaded what I've been trying so far to this repository: 
>>>>>> https://github.com/doorgan/formatter. The relevant file is 
>>>>>> https://github.com/doorgan/formatter/blob/main/lib/normalizer.ex as 
>>>>>> well as the tests.
>>>>>>
>>>>>> The approach I'm taking there is to walk the AST and manually wrap 
>>>>>> literals when I find them, according to the context(when possible). I 
>>>>>> think 
>>>>>> I'm able to produce the kind of AST the formatter would expect, and 
>>>>>> produces fairly adequate code, except for cases like mixed keyword lists 
>>>>>> ([1, 2, a: b]) for which I still have to figure out how to recreate. I 
>>>>>> had 
>>>>>> to add a literal? field to the literal blocks to distinguish them from 
>>>>>> regular blocks and prevent the normalizer from recursing infinitely. 
>>>>>> Maybe 
>>>>>> this could be avoided, I need to figure how, though.
>>>>>>
>>>>>> I would like to know if you think this is a good aproach, or I should 
>>>>>> try to change the various block_to_algebra and quoted_to_algebra to 
>>>>>> handle 
>>>>>> literals.
>>>>>>  I'm starting to believe this may be the cleanest aproach, and I 
>>>>>> would need to expand the state map to hold metadata from the parent 
>>>>>> node(so 
>>>>>> I can fill line numbers, or metadata like format: :keyword to keyword 
>>>>>> lists).
>>>>>>
>>>>>> El viernes, 7 de mayo de 2021 a las 11:07:31 UTC-3, José Valim 
>>>>>> escribió:
>>>>>>
>>>>>>> I think there are two fronts:
>>>>>>>
>>>>>>> 1. Today, all of the API the formatter uses, except the extraction 
>>>>>>> of code comments, is public. So providing a 
>>>>>>> string_to_quoted_with_comments 
>>>>>>> would be a logical next step. We only need to convert the comments from 
>>>>>>> a 
>>>>>>> tuple to a map before.
>>>>>>>
>>>>>>> 2. The second step is more complex and needs more research, which is 
>>>>>>> to figure out how exactly to change the formatter to accept general AST.
>>>>>>>
>>>>>>> Please coordinate between you because it seems some work may have 
>>>>>>> already been done in those areas. I will be glad to provide assistance 
>>>>>>> and 
>>>>>>> answer questions. :)
>>>>>>>
>>>>>>> On Fri, May 7, 2021 at 3:51 PM Tonći Galić <[email protected]> 
>>>>>>> wrote:
>>>>>>>
>>>>>>>> Hi folks,
>>>>>>>>
>>>>>>>> Nice to see someone got the ball rolling, I'm also interested (and 
>>>>>>>> would like to contribute). For me it's a bit unclear what the next 
>>>>>>>> steps 
>>>>>>>> would be? 
>>>>>>>> If someone could clarify, it'd be happy to spend some time on PR
>>>>>>>>
>>>>>>>> Best,
>>>>>>>> Tonći
>>>>>>>>
>>>>>>>> On Friday, May 7, 2021 at 6:15:48 AM UTC+2 José Valim wrote:
>>>>>>>>
>>>>>>>>> Correct. Those are the trade-offs. We could for example have 
>>>>>>>>> Code.string_to_quoted_formatter_options which returns the formatter 
>>>>>>>>> options 
>>>>>>>>> used for parsing the AST but then users must know that we now have a 
>>>>>>>>> special kind of AST. And nodes introduced by user may still not be 
>>>>>>>>> annotated - which means we still need to care about those scenarios.
>>>>>>>>>
>>>>>>>>> On Fri, May 7, 2021 at 5:07 AM i Dorgan <[email protected]> 
>>>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>>> Thanks for your thoughts!
>>>>>>>>>>
>>>>>>>>>> > If anyone is interested, I was playing with these ideas and you 
>>>>>>>>>> can see some example use cases here: 
>>>>>>>>>> https://github.com/wojtekmach/fix/blob/master/test/fix_test.exs. 
>>>>>>>>>> But exactly because Code.Formatter is private, I had to vendor it 
>>>>>>>>>> and that 
>>>>>>>>>> code broke on recent Elixir versions.
>>>>>>>>>>
>>>>>>>>>> I really like what you did there. With "that code broke on recent 
>>>>>>>>>> Elixir versions" you mean the addition of stepped ranges? I see that 
>>>>>>>>>> the 
>>>>>>>>>> wrapping of literals via the `literal_encoder` hasn't changed since 
>>>>>>>>>> June of 
>>>>>>>>>> 2019.
>>>>>>>>>>
>>>>>>>>>> > There is one issue about quoted_to_algebra though: the AST that 
>>>>>>>>>> the formatter works with is a special one, where the literals are 
>>>>>>>>>> wrapped 
>>>>>>>>>> in blocks so we can store their metadata. This means that, in order 
>>>>>>>>>> to have 
>>>>>>>>>> quotes_to_algebra, we would need to change the formatter to also 
>>>>>>>>>> handle 
>>>>>>>>>> “regular AST” or nodes with limited metadata.
>>>>>>>>>> > 
>>>>>>>>>> > It is doable, but it is work, and a requirement to expose said 
>>>>>>>>>> functionality.
>>>>>>>>>>
>>>>>>>>>> I'm exploring ways to achieve this, and I can think of two 
>>>>>>>>>> approaches:
>>>>>>>>>> a - traverse the received AST and wrap the literals in blocks
>>>>>>>>>> b - change the various functions used to convert the AST into 
>>>>>>>>>> algebra fragments so that they can also handle bare literals
>>>>>>>>>>
>>>>>>>>>> After some experimentation I saw that option a is doable, but I 
>>>>>>>>>> feel that I am recreating part of the work that the tokenizer 
>>>>>>>>>> already does 
>>>>>>>>>> and that it would become a burden to maintain whenever the tokenizer 
>>>>>>>>>> changes.
>>>>>>>>>> I haven't tried option b yet, I'm still trying to get familiar 
>>>>>>>>>> with the quoted -> algebra conversion(and algebra documents in 
>>>>>>>>>> general), 
>>>>>>>>>> but my first thought is that it would be hard to figure out over 
>>>>>>>>>> which 
>>>>>>>>>> literal a comment should be placed. I imagine that a quoted 
>>>>>>>>>> expression 
>>>>>>>>>> representing this code:
>>>>>>>>>> 1  def foo() do
>>>>>>>>>> 2    :hello
>>>>>>>>>> 3
>>>>>>>>>> 4    :elixir
>>>>>>>>>> 5
>>>>>>>>>> 6
>>>>>>>>>> 7    :world
>>>>>>>>>> 8  end
>>>>>>>>>> And a comment {5, {_, _}, "Hello!"}
>>>>>>>>>> If we don't have line number information, where should the 
>>>>>>>>>> comment be placed? We don't know where the literals are, they may be 
>>>>>>>>>> at 
>>>>>>>>>> lines 2, 3 and 4, or 2, 4 and 7, they could be anywhere. All we can 
>>>>>>>>>> tell is 
>>>>>>>>>> that the comment goes somewhere between lines 1 and 8, so any 
>>>>>>>>>> position 
>>>>>>>>>> would be ok. So having the formatter accept bare literals would mean 
>>>>>>>>>> having 
>>>>>>>>>> to work with insufficient data and it would produce a bad output. 
>>>>>>>>>> This 
>>>>>>>>>> issue is also present with option a, but changing the part of the 
>>>>>>>>>> formatter 
>>>>>>>>>> that generates the algebra document would essentially mean to 
>>>>>>>>>> *break* the formatter in multiple places. In summary, I'm not 
>>>>>>>>>> sure about the usefulness of a user supplied ast with no line 
>>>>>>>>>> numbers 
>>>>>>>>>> associated to literals, as it is hard to apropiately recreate the 
>>>>>>>>>> source 
>>>>>>>>>> code when comments are involved.
>>>>>>>>>> I'm not happy with neither approach and I will try to think of 
>>>>>>>>>> better solutions.
>>>>>>>>>>
>>>>>>>>>> On the other hand, the literal encoder is using a public api. A 
>>>>>>>>>> user can already generate AST from a string with the literals 
>>>>>>>>>> wrapped in a 
>>>>>>>>>> block via the :literal_encoder option of Code.string_to_quoted, so I 
>>>>>>>>>> think 
>>>>>>>>>> the literal token metadata should be considered public api(changes 
>>>>>>>>>> to it 
>>>>>>>>>> can already break third party code today). Wrapping a literal in a 
>>>>>>>>>> block 
>>>>>>>>>> and storing the token metadata in it has proven to be a very simple 
>>>>>>>>>> and 
>>>>>>>>>> practical solution to the problem of literals not carrying any 
>>>>>>>>>> metadata 
>>>>>>>>>> while still using valid AST, so maybe exposing that can also be 
>>>>>>>>>> considered 
>>>>>>>>>> as a viable alternative? This would go against my original position 
>>>>>>>>>> of "nor 
>>>>>>>>>> does it need to expose the private version of the AST used 
>>>>>>>>>> internally by 
>>>>>>>>>> the formatter", but in practical terms I think it would provide more 
>>>>>>>>>> value 
>>>>>>>>>> if it were exposed. The comments data structure would already be 
>>>>>>>>>> exposed 
>>>>>>>>>> and we would be requiring users to provide comments in that form, so 
>>>>>>>>>> I 
>>>>>>>>>> think requiring an AST with literals shaped in a particular way 
>>>>>>>>>> wouldn't be 
>>>>>>>>>> unreasonable. Of course, if that would be done, the fact that 
>>>>>>>>>> quoted_to_algebra requires an AST with literals wrapped in that way 
>>>>>>>>>> should 
>>>>>>>>>> be properly documented.
>>>>>>>>>> El jueves, 6 de mayo de 2021 a las 3:07:33 UTC-3, Wojtek Mach 
>>>>>>>>>> escribió:
>>>>>>>>>>
>>>>>>>>>>> Looking forward to any progress on this front.
>>>>>>>>>>>
>>>>>>>>>>> If anyone is interested, I was playing with these ideas and you 
>>>>>>>>>>> can see some example use cases here: 
>>>>>>>>>>> https://github.com/wojtekmach/fix/blob/master/test/fix_test.exs. 
>>>>>>>>>>> But exactly because Code.Formatter is private, I had to vendor it 
>>>>>>>>>>> and that 
>>>>>>>>>>> code broke on recent Elixir versions.
>>>>>>>>>>>
>>>>>>>>>>> On May 5, 2021, "José Valim" <[email protected]> wrote:
>>>>>>>>>>>
>>>>>>>>>>> I believe those ideas are promising. There is one issue about 
>>>>>>>>>>> quoted_to_algebra though: the AST that the formatter works with is 
>>>>>>>>>>> a 
>>>>>>>>>>> special one, where the literals are wrapped in blocks so we can 
>>>>>>>>>>> store their 
>>>>>>>>>>> metadata. This means that, in order to have quotes_to_algebra, we 
>>>>>>>>>>> would 
>>>>>>>>>>> need to change the formatter to also handle “regular AST” or nodes 
>>>>>>>>>>> with 
>>>>>>>>>>> limited metadata.
>>>>>>>>>>> It is doable, but it is work, and a requirement to expose said 
>>>>>>>>>>> functionality.
>>>>>>>>>>> About the comments, I like the suggestion. Although we should 
>>>>>>>>>>> probably move from a tuple to a map to avoid breaking changes in 
>>>>>>>>>>> the 
>>>>>>>>>>> future. A PR for this particular issue is very welcome!
>>>>>>>>>>> Thank you for the proposal and thinking about these problems.
>>>>>>>>>>> On Wed, May 5, 2021 at 21:16 i Dorgan <[email protected]> 
>>>>>>>>>>> wrote:
>>>>>>>>>>>
>>>>>>>>>>> Hi all,
>>>>>>>>>>>>
>>>>>>>>>>>> The motivation for this proposal is to make it easier for tools 
>>>>>>>>>>>> to alter and format elixir code while preserving the current 
>>>>>>>>>>>> behavior of 
>>>>>>>>>>>> the formatter. Most of the functionality is already there, and a 
>>>>>>>>>>>> little 
>>>>>>>>>>>> change in the APIs would enable a wide variety of new use cases.
>>>>>>>>>>>>
>>>>>>>>>>>> If we want to transform a piece of code from one form to 
>>>>>>>>>>>> another, we can modify the AST and then convert it back to a 
>>>>>>>>>>>> string. For 
>>>>>>>>>>>> example, a tool could detect the usage of `String.to_atom` and not 
>>>>>>>>>>>> only 
>>>>>>>>>>>> warn about unsafe string to atom conversion, but also give an 
>>>>>>>>>>>> option to 
>>>>>>>>>>>> automatically fix the issue, replacing it with 
>>>>>>>>>>>> `String.to_existing_atom`. 
>>>>>>>>>>>> The first part is already covered by tools like credo, but it 
>>>>>>>>>>>> seems that 
>>>>>>>>>>>> manipulating the source code itself is difficult, mostly because 
>>>>>>>>>>>> the AST 
>>>>>>>>>>>> does not contain information about comments and because 
>>>>>>>>>>>> `Macro.to_string` 
>>>>>>>>>>>> doesn't produce text that complies with the elixir coding 
>>>>>>>>>>>> conventions. For 
>>>>>>>>>>>> example, this code:
>>>>>>>>>>>> ```elixir
>>>>>>>>>>>> def foo(bar) do
>>>>>>>>>>>>   # Some comment
>>>>>>>>>>>>   :baz
>>>>>>>>>>>> end
>>>>>>>>>>>> ```
>>>>>>>>>>>> Would be printed as this:
>>>>>>>>>>>> ```elixir
>>>>>>>>>>>> def(fop(bar)) do
>>>>>>>>>>>>   :baz
>>>>>>>>>>>> end
>>>>>>>>>>>> ```
>>>>>>>>>>>> Tools like https://github.com/KronicDeth/intellij-elixir 
>>>>>>>>>>>> implement their own parsers to circumvent this issue, but I think 
>>>>>>>>>>>> it would 
>>>>>>>>>>>> be nice if it could be achieved with the existing parser in core 
>>>>>>>>>>>> elixir.
>>>>>>>>>>>>
>>>>>>>>>>>> I've seen other conversations where it was suggested to change 
>>>>>>>>>>>> the elixir AST to support comments, either adding a new comment 
>>>>>>>>>>>> node(breaking change) or using the nodes metadata, but the 
>>>>>>>>>>>> conclusion was 
>>>>>>>>>>>> that there was no clear preference on how to do this at the AST 
>>>>>>>>>>>> level, and 
>>>>>>>>>>>> being that the elixir tokenizer allows us to pass a function to 
>>>>>>>>>>>> process the 
>>>>>>>>>>>> comments, José suggested to keep the them on a side data structure 
>>>>>>>>>>>> instead 
>>>>>>>>>>>> of in the AST itself. This is what the Elixir formatter does.
>>>>>>>>>>>>
>>>>>>>>>>>> Currently the `Code.Formatter` module is private API used by 
>>>>>>>>>>>> the `Code.format_string` function. This means that the only way to 
>>>>>>>>>>>> format 
>>>>>>>>>>>> elixir code is by providing a string(or a file) to a function in 
>>>>>>>>>>>> the `Code` 
>>>>>>>>>>>> module. If we are transforming the code, however, what we have is 
>>>>>>>>>>>> a quoted 
>>>>>>>>>>>> expression, thus we don't have a way to turn it back into a string.
>>>>>>>>>>>>
>>>>>>>>>>>> At a high level, the `Code.Formatter.to_algebra` does three 
>>>>>>>>>>>> things:
>>>>>>>>>>>> 1. It extracts the comments from the source code
>>>>>>>>>>>> 2. It parses the source code into a quoted expression
>>>>>>>>>>>> 3. It takes the comments and the quoted expressions and merges 
>>>>>>>>>>>> them to produce an algebra document
>>>>>>>>>>>>
>>>>>>>>>>>> What I propose is to split the `Code.Formatter.to_algebra` 
>>>>>>>>>>>> considering those steps, and expose the functionality via the 
>>>>>>>>>>>> `Code` 
>>>>>>>>>>>> module. The reasoning is that if a user has access to both the ast 
>>>>>>>>>>>> and the 
>>>>>>>>>>>> comments, they can then transform the ast, and return back both 
>>>>>>>>>>>> the ast and 
>>>>>>>>>>>> comments to the formatter to produce an algebra document. *How 
>>>>>>>>>>>> they implement this is up to them* and Elixir doesn't need to 
>>>>>>>>>>>> give an opinion on how comments should be handled during those 
>>>>>>>>>>>> manipulations, nor does it need to expose the private version of 
>>>>>>>>>>>> the AST 
>>>>>>>>>>>> used internally by the formatter. If they want to merge comments 
>>>>>>>>>>>> into the 
>>>>>>>>>>>> metadata or use custom nodes, it's completely up to them, they 
>>>>>>>>>>>> just need to 
>>>>>>>>>>>> return back a valid quoted expression and a list of comments with 
>>>>>>>>>>>> their 
>>>>>>>>>>>> metadata.
>>>>>>>>>>>>
>>>>>>>>>>>> The other reason I think this should be done by exposing those 
>>>>>>>>>>>> functions is that there's a great a amount of work put into the 
>>>>>>>>>>>> formatter 
>>>>>>>>>>>> to turn the quoted expressions into formatted algebra documents, 
>>>>>>>>>>>> and I 
>>>>>>>>>>>> think all of that could be reused, eliminating the need for custom 
>>>>>>>>>>>> formatters.
>>>>>>>>>>>>
>>>>>>>>>>>> The workflow would be something like this:
>>>>>>>>>>>> ```elixir
>>>>>>>>>>>> {:ok, {quoted, comments}} = File.read!(path) |> 
>>>>>>>>>>>> Code.string_to_quoted_with_comments()
>>>>>>>>>>>> quoted  = do_some_manipulation(quoted , comments)
>>>>>>>>>>>> {:ok, doc} = Code.quoted_to_algebra(quoted, comments: comments)
>>>>>>>>>>>> new_source = Inspect.Algebra.format(doc, 80)
>>>>>>>>>>>> ```
>>>>>>>>>>>> I'm not married to those function names and return values, but 
>>>>>>>>>>>> I hope they serve to convey the idea.
>>>>>>>>>>>>
>>>>>>>>>>>> I already have some little examples of source code 
>>>>>>>>>>>> transformations using an API like the above, I'm working on 
>>>>>>>>>>>> reducing and 
>>>>>>>>>>>> tidying them, but in the meantime I would like to hear you 
>>>>>>>>>>>> opinions on this 
>>>>>>>>>>>> proposal.
>>>>>>>>>>>>
>>>>>>>>>>>> The only downside I can think of is that the `{line, 
>>>>>>>>>>>> {previous_eol, next_eol}, text}` format of the comments may be 
>>>>>>>>>>>> considered a 
>>>>>>>>>>>> private data structure, but the formatter hasn't changed much 
>>>>>>>>>>>> since 1.6(3 
>>>>>>>>>>>> years ago) and I think it could be considered stable enough to be 
>>>>>>>>>>>> exposed.
>>>>>>>>>>>>
>>>>>>>>>>>> -- 
>>>>>>>>>>>> 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 [email protected].
>>>>>>>>>>>> To view this discussion on the web visit 
>>>>>>>>>>>> https://groups.google.com/d/msgid/elixir-lang-core/5f431518-f555-48bb-a999-ec49f6423463n%40googlegroups.com
>>>>>>>>>>>>  
>>>>>>>>>>>> <https://groups.google.com/d/msgid/elixir-lang-core/5f431518-f555-48bb-a999-ec49f6423463n%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 [email protected].
>>>>>>>>>>>
>>>>>>>>>>> To view this discussion on the web visit 
>>>>>>>>>>> https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4Jxt-nAbwYKYkTv0wUAamm%2Bhm24B3DdKatD%2Bdgn0six1g%40mail.gmail.com
>>>>>>>>>>>  
>>>>>>>>>>> <https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4Jxt-nAbwYKYkTv0wUAamm%2Bhm24B3DdKatD%2Bdgn0six1g%40mail.gmail.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 [email protected].
>>>>>>>>>>
>>>>>>>>> To view this discussion on the web visit 
>>>>>>>>>> https://groups.google.com/d/msgid/elixir-lang-core/10a1735e-ed95-4c2d-8eb4-beabf193c214n%40googlegroups.com
>>>>>>>>>>  
>>>>>>>>>> <https://groups.google.com/d/msgid/elixir-lang-core/10a1735e-ed95-4c2d-8eb4-beabf193c214n%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 [email protected].
>>>>>>>>
>>>>>>> To view this discussion on the web visit 
>>>>>>>> https://groups.google.com/d/msgid/elixir-lang-core/43be368f-7383-43ad-886c-0e63d8bca3a9n%40googlegroups.com
>>>>>>>>  
>>>>>>>> <https://groups.google.com/d/msgid/elixir-lang-core/43be368f-7383-43ad-886c-0e63d8bca3a9n%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 [email protected].
>>>>>>
>>>>> To view this discussion on the web visit 
>>>>>> https://groups.google.com/d/msgid/elixir-lang-core/30f42fa5-b8c9-47ce-8f46-e90b800ecb3cn%40googlegroups.com
>>>>>>  
>>>>>> <https://groups.google.com/d/msgid/elixir-lang-core/30f42fa5-b8c9-47ce-8f46-e90b800ecb3cn%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 [email protected].
>>>
>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/elixir-lang-core/c4fbbfa3-0253-46d0-b90a-679117e8dc39n%40googlegroups.com
>>>  
>>> <https://groups.google.com/d/msgid/elixir-lang-core/c4fbbfa3-0253-46d0-b90a-679117e8dc39n%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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/3efe1224-0956-45ca-aed4-b671645030c3n%40googlegroups.com.

Reply via email to