« Back to channel list

#elixir-lang - 27 May 2019

« Back 1 day Forward 1 day »
[00:00:39] atk: has joined #elixir-lang
[00:15:33] netrino: has joined #elixir-lang
[00:24:21] Adkron: has joined #elixir-lang
[00:34:47] ariedler: has joined #elixir-lang
[00:43:03] Cloudflare: has joined #elixir-lang
[00:50:06] wsieroci: has joined #elixir-lang
[00:55:53] Adkron: has joined #elixir-lang
[00:59:48] netrino: has joined #elixir-lang
[01:01:31] orbyt_: has joined #elixir-lang
[01:17:13] sevenseacat: has joined #elixir-lang
[01:32:53] tomterl: has joined #elixir-lang
[01:33:13] Adkron: has joined #elixir-lang
[01:38:51] netrino: has joined #elixir-lang
[01:42:42] blahdodo: has joined #elixir-lang
[01:44:10] wsieroci: has joined #elixir-lang
[02:00:44] orbyt_: has joined #elixir-lang
[02:02:14] elixir-lang501: has joined #elixir-lang
[02:05:48] Adkron: has joined #elixir-lang
[02:23:18] netrino: has joined #elixir-lang
[02:32:56] blahdodo: has joined #elixir-lang
[02:38:17] wsieroci: has joined #elixir-lang
[02:49:06] Adkron: has joined #elixir-lang
[03:04:29] harfangk: has joined #elixir-lang
[03:07:51] netrino: has joined #elixir-lang
[03:18:37] Saukk: has joined #elixir-lang
[03:21:19] Adkron: has joined #elixir-lang
[03:32:33] wsieroci: has joined #elixir-lang
[03:43:38] gvaughn: has joined #elixir-lang
[03:45:36] Adkron: has joined #elixir-lang
[03:46:56] netrino: has joined #elixir-lang
[04:08:12] Exuma: has joined #elixir-lang
[04:08:25] notzmv: has joined #elixir-lang
[04:25:58] netrino: has joined #elixir-lang
[04:26:11] Adkron: has joined #elixir-lang
[04:52:45] gvaughn: has joined #elixir-lang
[05:03:23] gde33: has joined #elixir-lang
[05:04:24] mbuf: has joined #elixir-lang
[05:05:01] netrino: has joined #elixir-lang
[05:07:20] Adkron: has joined #elixir-lang
[05:22:40] DeadTrickster: has joined #elixir-lang
[05:31:58] Mieserkadser: has joined #elixir-lang
[05:39:50] ur5us: has joined #elixir-lang
[05:43:23] kyrylo: has joined #elixir-lang
[05:46:35] Adkron: has joined #elixir-lang
[05:49:38] kdisneur: has joined #elixir-lang
[05:52:02] serafeim: good morning
[05:54:07] netrino: has joined #elixir-lang
[06:11:27] dtzuzu: has joined #elixir-lang
[06:25:35] Adkron: has joined #elixir-lang
[06:28:06] tuacker: has joined #elixir-lang
[06:31:15] kapilp: has joined #elixir-lang
[06:33:21] netrino: has joined #elixir-lang
[06:34:10] gvaughn: has joined #elixir-lang
[06:43:51] m1dnight_: has joined #elixir-lang
[06:53:30] kdisneur: has joined #elixir-lang
[07:02:53] BitBot: has joined #elixir-lang
[07:04:54] rom1504: has joined #elixir-lang
[07:09:46] rom1504: has joined #elixir-lang
[07:12:34] Adkron: has joined #elixir-lang
[07:30:21] gvaughn: has joined #elixir-lang
[07:34:54] kdisneur: has joined #elixir-lang
[07:56:52] netrino: has joined #elixir-lang
[07:57:08] Adkron: has joined #elixir-lang
[07:59:31] blahdodo: has joined #elixir-lang
[08:05:08] lexmag: has joined #elixir-lang
[08:06:11] netrino: has joined #elixir-lang
[08:12:42] gvaughn: has joined #elixir-lang
[08:15:18] netrino: has joined #elixir-lang
[08:16:07] ur5us: has joined #elixir-lang
[08:20:03] kdisneur: has joined #elixir-lang
[08:24:26] netrino: has joined #elixir-lang
[08:35:43] jkva: has joined #elixir-lang
[08:41:36] Adkron: has joined #elixir-lang
[08:43:43] hypercore: has joined #elixir-lang
[08:47:54] lovesponge: has joined #elixir-lang
[08:50:54] Mieserkadser: has joined #elixir-lang
[09:03:03] kdisneur: has joined #elixir-lang
[09:03:46] netrino: has joined #elixir-lang
[09:12:17] Sgeo__: has joined #elixir-lang
[09:13:12] lexmag: has joined #elixir-lang
[09:18:06] hypercore: has joined #elixir-lang
[09:19:56] wonko7: has joined #elixir-lang
[09:21:45] rawtaz: is anyone aware of an AFTN parser for Elixir (or Erlang, i suppose)? https://en.wikipedia.org/wiki/Aeronautical_Fixed_Telecommunication_Network#AFTN_Message_Format
[09:22:06] Adkron: has joined #elixir-lang
[09:22:34] PragTob: has joined #elixir-lang
[09:22:48] dysfun: i think you're likely to get more results googling
[09:23:23] rawtaz: i have been googling, or ducking, to be more precise ;)
[09:23:32] hypercore: guys is it worht using a managed database if i think my website will be popular?
[09:23:32] rawtaz: didnt find any, so i thought why not ask here anyway
[09:23:37] rawtaz: cheers though dysfun
[09:23:47] hypercore: ($15/month)
[09:24:13] dysfun: you don't get a lot of database for $15/month
[09:24:34] hypercore: 1gb ram, 1vCPU, 10GB
[09:24:40] hypercore: that's enough isn't it?
[09:24:52] hypercore: and i could upgrade if i need to later
[09:25:02] dysfun: depends how much data you're talking about
[09:25:06] dysfun: how you will access it
[09:25:55] hypercore: dysfun: nothing huge, just a standard crud app
[09:26:27] hypercore: not sure what other ways of accessing the data exist other than what normally happens
[09:29:06] blahdodo: has joined #elixir-lang
[09:41:36] dch: hypercore: for $50/month you can get 8x the RAM, 8 actual cores (not hyperthread garbage), on real tin. https://www.packet.com/cloud/servers/t1-small/ I run a few elixir apps on these and its absolutely excellent. I'd not be comfortable about running a busy DB on a 1GB/1vCPU instance, but then it does depend on what you mean by "popular".
[09:42:28] Nicd-: that's not managed though
[09:42:33] dch: I'm sure whatever cloud provider you're using can allow you to upgrade the system easily if need be. If you put a load balancer in front right from the beginning, you can move to a bigger instance without downtime if needed.
[09:42:48] netrino: has joined #elixir-lang
[09:43:25] hypercore: digital ocean
[09:43:39] dch: Nicd-: nope, I guess I don't ever think a managed DB is worth it for a serious app. Each to their own?
[09:46:34] dch: the restrictions that DO have look pretty onerous https://www.digitalocean.com/docs/databases/overview
[09:47:20] hypercore: so don't worry about it?
[09:48:04] gvaughn: has joined #elixir-lang
[09:48:32] koollman: hypercore: don't worry until it is likely to become a problem. And maybe have a plan for that
[09:51:20] hypercore: koollman: fair enough
[09:53:48] koollman: hypercore: don't pay for expensive stuff too early if you can avoid it, but have a plan for 'sudden success' ready. (which can be "I have backups that I can restore on a much more expensive platform". until you need that plan, it is mostly free :) )
[10:03:59] Adkron: has joined #elixir-lang
[10:09:53] hypercore: has joined #elixir-lang
[10:10:54] dtzuzu: has joined #elixir-lang
[10:21:48] netrino: has joined #elixir-lang
[10:24:04] serafeim: hello. is there a way to disable "mix ecto.reset" for prod ?
[10:25:04] BitBot: has joined #elixir-lang
[10:25:09] serafeim: this seems like an e-z way to do something stupid
[10:30:35] Nicd-: if you use a release, mix tasks won't exist in production
[10:37:40] Phylock: has joined #elixir-lang
[10:40:19] kdisneur: has joined #elixir-lang
[10:47:16] Adkron: has joined #elixir-lang
[10:48:22] anykey: has joined #elixir-lang
[10:49:47] oldnborg: has joined #elixir-lang
[10:49:56] Phylock: has joined #elixir-lang
[10:57:25] serafeim: Nicd-: lol i was planning on *not* using a release :|
[10:58:55] Nicd-: releases are the de facto method currently so things are geared towards that
[11:00:33] netrino: has joined #elixir-lang
[11:04:22] serafeim: Nicd-: ok i understand
[11:05:39] serafeim: another question. I am using the following query: Repo.all(Withholding) |> Repo.preload([:authority]) to preload some the authority foreign key... now, authority has *another* foreign key (i.e authority_kind). how can I also load this in my query ?
[11:06:18] serafeim: is this possible using this syntax or i'll need to fall back to from Withholding and doing a left join ?
[11:23:36] Adkron: has joined #elixir-lang
[11:24:16] gvaughn: has joined #elixir-lang
[11:24:30] kdisneur: has joined #elixir-lang
[11:29:03] kyrylo: has joined #elixir-lang
[11:40:12] lexmag: has joined #elixir-lang
[11:43:32] wonko7: has joined #elixir-lang
[11:57:45] kdisneur: has joined #elixir-lang
[12:01:56] Adkron: has joined #elixir-lang
[12:07:26] lexmag: has joined #elixir-lang
[12:09:34] netrino: has joined #elixir-lang
[12:22:42] kdisneur: has joined #elixir-lang
[12:33:03] hypercore: has joined #elixir-lang
[12:33:19] Avinash: has joined #elixir-lang
[12:41:48] tnez: has joined #elixir-lang
[12:43:54] Adkron: has joined #elixir-lang
[12:46:32] lauromoura_: has joined #elixir-lang
[12:48:34] netrino: has joined #elixir-lang
[12:58:41] wonko7: has joined #elixir-lang
[13:01:41] atomicnumber1: has joined #elixir-lang
[13:01:51] gvaughn: has joined #elixir-lang
[13:04:03] kdisneur: has joined #elixir-lang
[13:14:09] serafeim: I am using the following query: `Repo.all(Withholding) |> Repo.preload([:authority])` to preload some the authority foreign key... now, authority has *another* foreign key (i.e authority_kind). how can I also load this in my query ? is this possible using this pipe syntax or i'll need to fall back to `from Withholding` and doing a left join ?
[13:14:29] serafeim: (i'd rather avoid the left join cause i don't remember the syntax by heart)
[13:17:59] waltfy: has joined #elixir-lang
[13:21:44] Gazler: serafeim: You mean like Repo.preload([:authority, :other_thing])
[13:22:07] Gazler: Oh, I misread, it is an association on authority.
[13:22:14] serafeim: gazler: ha ha something like this *but* the :other_thing is a foreign key of :authority !
[13:22:22] Gazler: You want Repo.preload(authority: :authority_kind)
[13:22:52] serafeim: gazler: thanks let me test it
[13:23:01] Gazler: https://hexdocs.pm/ecto/Ecto.Repo.html#c:preload/3-examples
[13:24:03] serafeim: gazler: great thanks! and i guess i could go as "deep" I want in the nesting
[13:24:13] Gazler: serafeim: Yeah
[13:26:01] Adkron: has joined #elixir-lang
[13:27:33] netrino: has joined #elixir-lang
[13:28:02] kdisneur: has joined #elixir-lang
[13:34:47] hypercore: has joined #elixir-lang
[13:45:32] Adkron: has joined #elixir-lang
[13:47:39] hypercore: has joined #elixir-lang
[13:52:41] wonko7: has joined #elixir-lang
[13:59:50] BitBot: has joined #elixir-lang
[14:06:33] netrino: has joined #elixir-lang
[14:17:36] balackbee: has joined #elixir-lang
[14:23:06] Adkron: has joined #elixir-lang
[14:30:30] mbuf: has joined #elixir-lang
[14:35:53] hypercore: has joined #elixir-lang
[14:38:02] BitBot: has joined #elixir-lang
[14:43:27] gvaughn: has joined #elixir-lang
[14:45:37] netrino: has joined #elixir-lang
[14:46:12] kdisneur: has joined #elixir-lang
[14:49:49] kapilp: has joined #elixir-lang
[14:51:07] greengriminal: has joined #elixir-lang
[14:59:36] wsieroci: has joined #elixir-lang
[15:00:12] kdisneur: has joined #elixir-lang
[15:19:02] slashrsm: has joined #elixir-lang
[15:19:40] jeffro: has joined #elixir-lang
[15:22:14] tuacker: has joined #elixir-lang
[15:22:38] gvaughn: has joined #elixir-lang
[15:24:36] netrino: has joined #elixir-lang
[15:29:37] heimann: has joined #elixir-lang
[15:32:50] kdisneur: has joined #elixir-lang
[15:50:13] BitBot: has joined #elixir-lang
[16:03:36] netrino: has joined #elixir-lang
[16:05:22] BitBot: has joined #elixir-lang
[16:22:14] kdisneur: has joined #elixir-lang
[16:38:58] nickjj: i'm curious, how would you guys handle this changeset / data model set up
[16:39:09] dimitarvp: has joined #elixir-lang
[16:39:26] nickjj: let's say you had "discounts" and "packages" , and a "discount_packages" join table and then you used has_many throughs to wire it all up
[16:40:07] nickjj: and when creating discounts, you can pick 0 or more packages to apply it to -- this is really the only time you would ever write to the discount_packages join table
[16:40:57] nickjj: so what i did was in the discount_packages changeset, i made the package_id optional and also set a FK constraint on it -- so far so good, this is working
[16:41:47] nickjj: but the problem is when i want to add a discount to apply to all packages, i don't want to insert 10 records for 10 packages, instead i wanted to set null to the package_id -- but when i try to do this with the above changeset, ecto says a null package_id is invalid
[16:42:17] PragTob: has joined #elixir-lang
[16:42:33] nickjj: and i just skip adding the discount_packages to the discount changeset then nothing gets written to the discount_packages table (but that doesn't work for my use case since it tracks other meta data that i need)
[16:42:38] netrino: has joined #elixir-lang
[17:06:07] gde33: has joined #elixir-lang
[17:06:23] lpil52: has joined #elixir-lang
[17:09:34] lpil: has joined #elixir-lang
[17:10:18] jnoon: nickjj: so i understand the thinking: so discount_packages has fields discount_id, package_id. and a discount_packages row with a null package_id signifies it belongs to every package?
[17:10:53] nickjj: jnoon, correct. i'm open for suggestions on how to better model that, but that is the current implementation
[17:12:57] jnoon: nickjj: i would rethink that first (strongly IMO). that is creating more complicated logic for determining which discounts are associated with a package and more application-logic to do it correctly
[17:14:33] nickjj: a discount can be applied to 1 or more packages , but i really wanted to avoid having some application logic that says "if 0 packages were selected, then go ahead and create 100 discount_packages rows which is 1 for each package of every course)
[17:15:54] jnoon: nickjj: lets say though you keep that.. list_discounts(package) looks like discounts … where dp.package_id is null or dp_package_id = package.id
[17:16:46] nickjj: jnoon, yep, i didn't get that far yet but that was the plan
[17:18:38] jnoon: nickjj: creating the discount is just create_discount(attrs) then create_discount_package(attrs_with_nil_package_id). maybe its not as bad as i thought. usually i try to avoid things you have to "know" to get the right result in the database and keep it fully relational, but this might be a case
[17:18:40] nickjj: but more specifically on how i plan to use discounts, it would be "on course (package) checkout page, if discount code is present, lookup code from discounts and then see if it's available to all packages or this specific package"
[17:18:57] lpil: has joined #elixir-lang
[17:20:00] nickjj: the problem i'm trying to solve is to make sure a discount_id is only ever listed once in discount_packages if package_id happens to be null
[17:21:21] nickjj: because you could totally have a JNOON25 discount that applies to package A and B from course 1 , and also have a JNOON25 discount that applies to package A from course 2 -- but you cannot have a JNOON25 discount that applies to all packages twice (that doesn't make sense)
[17:21:22] jnoon: i *think* unique_index would do that already… [:discount_id, :package_id].
[17:21:33] hypercore: has joined #elixir-lang
[17:21:41] netrino: has joined #elixir-lang
[17:21:43] nickjj: right, the problem lies with package_id being optionally null
[17:23:47] jnoon: ah, so discount_id: 1, package_id: null and discount_id: 1, package_id: 2 should not be allowed in your case, but discount_id: 1, package_id: 1 and discount_id: 1, package_id: 2 should?
[17:25:26] nickjj: https://gist.github.com/nickjj/8dd5af9c859560b25f3f9666f965ae2f
[17:25:32] nickjj: that is ok/bad states
[17:26:10] jnoon: weird, the unique_index allows that?
[17:26:40] nickjj: the unique_index will prevent the third example from happening (reload if you don't see the 3rd example)
[17:26:49] nickjj: but the unique_index allows the 2nd example to happen multiple times
[17:27:35] nickjj: i think i may have solved it, but i haven't gotten to checking it yet with changeset validations , but this correctly blocks it at the db level:
[17:27:44] nickjj: execute("CREATE UNIQUE INDEX discount_packages_discount_id_package_id_allow_null_index ON discount_packages (discount_id, coalesce(package_id, -1));"
[17:28:05] jnoon: got it, ya looking at the postgresql docs and see that about nulls… i bet there is a way, checking!
[17:28:27] nickjj: with that added, the DB will properly block the 1 NULL combo from appearing more than once, while properly allowing/disallowing the other examples
[17:29:11] jnoon: ya i like that, seems like a good solution
[17:29:12] nickjj: the -1 seems crucial, i tried NULL and "" for those values but nothing else worked -- but this stuff is a bit above my paygrade, just googling basically and found that example
[17:31:31] jnoon: well the index (discount_id, coalesce(package_id, -1)) discount_id: 1, package_id: 1 will be (1,1) and discount_id: 1, package_id: null will be (1,-1). its just forcing a value so it can make a proper index for each row. coalesce is like foo || -1
[17:32:39] jnoon: so if package_id is an integer column, then -1 makes sense. if you were using uuids for primary keys then you would have to change it… just depends on the column type
[17:33:25] blahdodo: has joined #elixir-lang
[17:33:39] nickjj: yep it is an integer fk reference
[17:33:58] jnoon: cool, and -1 is never going to be used, so you are good there
[17:34:46] kyrylo: has joined #elixir-lang
[17:36:09] nickjj: yeah, seems to all work with ecto too
[17:37:27] nickjj: thanks for the clarification on things too, helps a lot to get a 2nd opinion / back and forth on these things
[17:38:01] jnoon: sweet! ya ecto is pretty cool. im pretty new to it and converting some node and ruby stuff and did something with ecto that was really elegant in comparison to what it was in the other codebases. took a while to wrap my head around it and get it right, but its like once you get it right, its just rock solid and done!
[17:39:34] nickjj: yeah, still getting used to it myself, but i'm feeling the same way, once things start to semi-click, it's so clean
[17:45:33] wonko7: has joined #elixir-lang
[17:48:54] tallysmartins_: has joined #elixir-lang
[17:53:48] wsieroci: has joined #elixir-lang
[18:00:54] netrino: has joined #elixir-lang
[18:02:22] Robdor: has joined #elixir-lang
[18:14:35] orbyt_: has joined #elixir-lang
[18:14:52] wsieroci: has joined #elixir-lang
[18:24:16] squall: has joined #elixir-lang
[18:28:02] mahmudov: has joined #elixir-lang
[18:35:03] Robdor: has joined #elixir-lang
[18:39:57] netrino: has joined #elixir-lang
[18:43:42] Adkron: has joined #elixir-lang
[18:49:04] lpil: has joined #elixir-lang
[19:19:01] netrino: has joined #elixir-lang
[19:24:17] joedevivo: has joined #elixir-lang
[19:24:44] lpil52: has joined #elixir-lang
[19:27:38] marceldegraaf_: has joined #elixir-lang
[19:28:53] Adkron: has joined #elixir-lang
[19:29:52] strmpnk: has joined #elixir-lang
[19:31:18] benoitc: has joined #elixir-lang
[19:31:53] metalrain: has joined #elixir-lang
[19:32:24] dch: has joined #elixir-lang
[19:33:57] squall: has joined #elixir-lang
[19:40:26] BBHoss: has joined #elixir-lang
[19:40:32] bcavileer: has joined #elixir-lang
[19:40:35] strmpnk: has joined #elixir-lang
[19:40:35] metalrain: has joined #elixir-lang
[19:40:35] joedevivo: has joined #elixir-lang
[19:40:40] pmbauer: has joined #elixir-lang
[19:40:43] marceldegraaf_: has joined #elixir-lang
[19:40:44] ericmj: has joined #elixir-lang
[19:40:47] dch: has joined #elixir-lang
[19:41:00] avdi: has joined #elixir-lang
[19:41:04] msch: has joined #elixir-lang
[19:41:28] danmcclain_: has joined #elixir-lang
[19:42:00] jeregrine: has joined #elixir-lang
[19:42:38] jameshaydon: has joined #elixir-lang
[19:42:44] CornishPasty: has joined #elixir-lang
[19:43:09] manveru: has joined #elixir-lang
[19:43:18] whatyouhide: has joined #elixir-lang
[19:44:26] micmus: has joined #elixir-lang
[19:44:31] jhill: has joined #elixir-lang
[19:45:39] hansihe_: has joined #elixir-lang
[19:46:10] adamkittelson_: has joined #elixir-lang
[19:46:12] chazlever: has joined #elixir-lang
[19:46:32] ckrailo: has joined #elixir-lang
[19:46:36] marten: has joined #elixir-lang
[20:07:01] Adkron: has joined #elixir-lang
[20:08:23] netrino: has joined #elixir-lang
[20:20:16] orbyt_: has joined #elixir-lang
[20:35:40] nickjj: is there anything in ecto that allows you to define a bunch of validation rules for many different attributes, but skip doing all of those checks if the attribute being validated isn't cast?
[20:38:57] lexmag: has joined #elixir-lang
[20:42:56] __charly__: has joined #elixir-lang
[20:47:33] netrino: has joined #elixir-lang
[20:48:01] Adkron: has joined #elixir-lang
[20:48:39] helmut_1: has joined #elixir-lang
[20:49:51] helmut_1: has left #elixir-lang: ()
[20:51:27] nickjj: for clarity, this is what i'm trying to do https://gist.github.com/nickjj/98d4dcfe60656594c5f47224cf41e168
[20:54:39] ur5us: has joined #elixir-lang
[20:54:57] __charly__: has joined #elixir-lang
[21:04:46] micmus: nickjj: this should already work for everything other than validate_required - all normal validations run only if the value is changed (so it was casted). To fix the required validation you can take the set intersection of the default required fields and allowed fields
[21:06:12] nickjj: micmus, i tried moving the required validations out of the allowed changeset just to see what happens, but some other validations still run that shouldn't
[21:06:37] nickjj: i have an update_change in there that tries to get applied to a field that's not cast
[21:07:45] nickjj: also what if you don't want all allowed attributes to be required? i'm not sure how that could be automated with a set intersection
[21:09:31] micmus: nickjj: update_change shouldn't run if the value wasn't changed
[21:09:39] micmus: so that should be fine too
[21:11:08] micmus: `MapSet.intersection(MapSet.new([:email, :username, :hex_color]), MapSet.new([:email]))` => `MapSet.new([:email])` it only retains elements that are in both sets. But yeah, extracting it out is a good solution too. And probably simpler to understand
[21:14:29] nickjj: micmus, does the ordering of which validations you put first matter?
[21:14:48] micmus: i don't think so
[21:15:16] nickjj: in other words, doing this should be fine in any case? https://gist.github.com/nickjj/4074fc1021e17741a22020ba29abd996
[21:15:35] nickjj: basically do the generic changeset, and then always put my changeset specific validations after it?
[21:23:38] Adkron: has joined #elixir-lang
[21:25:40] nickjj: also wow, thanks for the tip on the mapset, it works as long as you run MapSet.to_list/1 on it to pass to the required validation
[21:26:36] netrino: has joined #elixir-lang
[21:36:07] qgnox: has joined #elixir-lang
[22:00:40] Adkron: has joined #elixir-lang
[22:05:37] netrino: has joined #elixir-lang
[22:09:27] blahdodo: has joined #elixir-lang
[22:31:15] orbyt_: has joined #elixir-lang
[22:38:05] Adkron: has joined #elixir-lang
[22:44:35] netrino: has joined #elixir-lang
[22:53:04] drincruz: has joined #elixir-lang
[23:06:52] adolfont: has joined #elixir-lang
[23:09:30] adolfont: http://www.gotw.ca/publications/concurrency-ddj.htm
[23:14:36] Adkron: has joined #elixir-lang
[23:23:36] netrino: has joined #elixir-lang
[23:56:16] Adkron: has joined #elixir-lang