Activity Graph

Page 1 of 2 | Next »


[11:16:38] micmus: nox: there are some additional literals that are dynamically allocated by the loader
[11:17:23] micmus: like funs that don't capture the environment or tuple keys for literal map construction
[11:18:03] micmus: nox: e.g. `make_fun` for a function that does not capture the environment is transformed into `mov x0 <literal>`
[12:29:27] micmus: josevalim: maybe it has something to do with collisions, but not sure. I've never really looked at the OTP implementation


[02:52:56] micmus: Quit: Connection closed for inactivity
[09:44:52] micmus: has joined #elixir-lang


[06:50:28] micmus: *.net *.split
[07:16:46] micmus: has joined #elixir-lang
[08:27:06] micmus: *.net *.split
[08:35:42] micmus: has joined #elixir-lang
[16:26:19] micmus: whatyouhide: pong


[17:25:22] micmus: has joined #elixir-lang


[12:10:52] micmus: Quit: Connection closed for inactivity


[03:26:43] micmus: Quit: Connection closed for inactivity
[06:04:21] micmus: has joined #elixir-lang
[07:39:50] micmus: nox: I've never thought about the loader that way, more like a rule engine
[17:03:52] micmus: Quit: Connection closed for inactivity
[23:27:58] micmus: has joined #elixir-lang


[01:05:30] micmus: Quit: Connection closed for inactivity
[05:21:10] micmus: has joined #elixir-lang
[15:45:38] micmus: serafeim: see recon and recon_trace or redbug. Or the builtin erlang dbg module
[15:46:07] micmus: serafeim: they basically allow you to subscribe to various vm events like gc or messages sent/received or functions called
[15:47:26] micmus: You can express something like "notify me when a function F.x/2 is called when the first argument is a list of 2 elelemnts" and similar


[05:25:30] micmus: Quit: Connection closed for inactivity
[06:16:39] micmus: has joined #elixir-lang


[11:49:10] micmus: mdbm: I'd say it does, but in a way where the conventional configuration is generated into your project and not implicit in the platform, so it's much easier to discover and change if needed


[10:53:00] micmus: has joined #elixir-lang
[13:02:46] micmus: Quit: Connection closed for inactivity
[13:07:15] micmus: has joined #elixir-lang
[17:52:45] micmus: Quit: Connection closed for inactivity
[21:56:00] micmus: has joined #elixir-lang


[04:41:15] micmus: Quit: Connection closed for inactivity


[09:42:20] micmus: Quit: Connection closed for inactivity
[12:12:05] micmus: has joined #elixir-lang


[10:02:20] micmus: Quit: Connection closed for inactivity
[10:21:43] micmus: has joined #elixir-lang


[10:24:41] micmus: lanodan: in general that might not work that well, most libraries assume they will be compiled in a particular project and can offer different features depending on other packages present during compilation, etc
[16:40:33] micmus: josevalim: on mobile. What's up?
[16:44:48] micmus: First a xor will give you places where both have same value (1 or 0), then an and will clear those ones
[16:45:34] micmus: tristan__: i don't think that would work since that would carry over - as far as I understood the task is not to carry between bits
[16:48:01] micmus: josevalim: one interesting data structure for bitsets over large ranges are roaring bitmaps
[16:48:20] micmus: They give both efficiency and low memory use
[16:48:51] micmus: In general it's a compressed bitset
[16:48:54] micmus: https://roaringbitmap.org
[16:49:21] micmus: Not sure how that would perform in erlang
[16:53:32] micmus: josevalim: is that for the liveness analysis?
[16:54:32] micmus: josevalim: well, with an ordset you pay only for the things you have in there, with a bitset you also pay for things that are not, so it's not that great when the sets are sparse
[17:08:30] micmus: No idea 😛
[18:32:13] micmus: josevalim: nice


[20:08:09] micmus: Quit: Connection closed for inactivity
[22:21:47] micmus: has joined #elixir-lang


[08:11:21] micmus: Quit: Connection closed for inactivity
[14:48:32] micmus: has joined #elixir-lang


[20:53:20] micmus: gamache: if your services are truly stateless and all the libraries you use are stateless, it's probably fine & easy to use. As soon as you introduce state it's another story. Most libraries don't come with proper appups, so any upgrade to them is almost impossible, if you have servers you need to migrate them properly, ... it's just a lot of extra things you need to do, over stapping on some standard blue-green thingy
[21:00:10] micmus: gamache: what do you do when you have some of those harder upgrades? like libraries, etc? Do you accept the downtime?


[17:32:02] micmus: Quit: Connection closed for inactivity
[18:43:15] micmus: has joined #elixir-lang


[01:37:08] micmus: Quit: Connection closed for inactivity
[06:35:10] micmus: has joined #elixir-lang


[01:31:44] micmus: Quit: Connection closed for inactivity
[06:31:33] micmus: has joined #elixir-lang
[11:42:46] micmus: Quit: Connection closed for inactivity
[15:40:52] micmus: has joined #elixir-lang
[17:12:19] micmus: icecreamcohen: going to the airport right now, so not really 😛
[17:12:38] micmus: For something quick, I'm on mobile
[21:50:06] micmus: Quit: Connection closed for inactivity
[23:27:26] micmus: has joined #elixir-lang


[03:10:32] micmus: Quit: Connection closed for inactivity
[06:48:37] micmus: has joined #elixir-lang


[05:35:58] micmus: has joined #elixir-lang
[06:03:05] micmus: serafeim: try rm -rf _build and recompiling, it might be that updating deps didn't purge all the compiled files that it should have
[06:12:55] micmus: yeah, it's some generated code that fails
[06:13:06] micmus: it might be that the versions of two libraries are not compatible for some reason
[06:19:25] micmus: the ex_audit package seems to be using a lot of ecto internals
[06:19:42] micmus: ecto doesn't guarantee any compatibility for functions that are not public and documented
[10:52:48] micmus: serafeim: you most likely didn't import Ecto.Query into the context where you're writing this
[10:53:28] micmus: so the compiler doesn't know it's a macro and tries to treat it as a regular function call
[13:41:59] micmus: heyohiho3: I'd say parts of the elixir stdlib could be good for that. Elixir is primarily written in elixir and most stdlib modules are self-contained
[13:47:28] micmus: heyohiho3: Enum might be a good place, in particular the specialization for lists in there, the whole enumerable protocol is also interesting


[14:30:06] micmus: nickjj: since you're probably going to be reading the data much more frequently than writing it, it usually makes sense to normalize the data during writes
[14:30:27] micmus: nickjj: for case-less comparisons, you could also consider the citext postgres type
[18:36:07] micmus: Quit: Connection closed for inactivity
[20:43:49] micmus: has joined #elixir-lang
[23:23:38] micmus: Quit: Connection closed for inactivity


[11:56:26] micmus: has joined #elixir-lang


[04:45:13] micmus: Quit: Connection closed for inactivity
[06:44:41] micmus: has joined #elixir-lang
[13:25:16] micmus: pushpa: could it be that mount doesn't call fetch?
[22:41:51] micmus: Quit: Connection closed for inactivity


[02:25:12] micmus: Quit: Connection closed for inactivity
[06:10:48] micmus: has joined #elixir-lang


[09:49:45] micmus: Miyu-saki: `Enum.group_by(list, &Map.get(&1, :x), &Map.delete(&1, :x))`
[10:00:02] micmus: Miyu-saki: yeah, there's MapSet - it's faster and uses less memory than the old implementations (including HashSet), so there's no reason for polymorphism (Set)
[16:39:29] micmus: Miyu-saki: it's not consumed as such, though - it's consumed as a collection of dependencies, so a list of tuples works great for that
[19:46:37] micmus: Miyu-saki: Module.safe_concat


[14:58:38] micmus: rawtaz: there are extensive release notes on every release
[15:00:49] micmus: Everybody who creates content can decide how to distribute it however they please, they don't owe anybody releasing materials for free
[15:06:05] micmus: rawtaz: the ebook is almost 200 pages
[15:06:29] micmus: sorry, a little over 200


[09:52:43] micmus: mdbm_: no. You need to start your repo - you need to start db connections and the whole machinery to manage them - it's a lot of state
[09:52:54] micmus: dependencies are orthogonal to that
[09:54:08] micmus: mdbm_: if dependencies have or not state is irrelevant and something you don't need to care about
[09:54:18] micmus: it's also in no way related to your app having state
[09:54:31] micmus: mdbm_: every hex package is an application
[09:54:40] micmus: if you don't have a supervision tree, it's also an application
[09:55:08] micmus: an application is a group of modules combined with some logic to start and stop it. In particular that logic might be to do nothing
[09:55:45] micmus: serafeim: because that's how it was designed
[09:56:52] micmus: serafeim: it is an application
[09:56:59] micmus: serafeim: every mix project is an application
[09:57:26] micmus: it's an application without a supervision tree - still an application
[09:58:21] micmus: mdbm_: you basically always have an application. What the book tells you to do is to modify the logic for starting your application to include starting database connections
[09:59:27] micmus: as I said - that logic might be to do nothing
[09:59:51] micmus: and that's what the mix new generator does by default


[09:38:36] micmus: dysfun: that further shows how rarely you use by-index access to tuples ;)
[15:22:14] micmus: benwilson512: you mean you want to do that annoying thing when I can't have multiple tabs open with the same site? :P


[09:55:48] micmus: mdbm: see the example at the bottom of this section on how to make it less verbose https://hexdocs.pm/ecto/Ecto.Schema.html#module-schema-attributes
[09:58:26] micmus: mdbm: we're actively avoiding global configs for ecto. Imagine if you have now two apps running together and you change the global config - now the other app explodes
[09:58:51] micmus: it's convenient in the short run, but it causes problems in the long run
[09:59:54] micmus: it's more or less a package or set of modules with an optional logic to "start" and "stop" them whatever that might mean in a specific context
[10:00:22] micmus: mdbm: and what I showed you is more or less a "config per app" approach ;)
[10:04:19] micmus: Yeah, I think it shouldn't override it if the value already exists
[11:42:34] micmus: jkva: spawn, spawn_link & friends return the pid of the newly spawned process
[11:43:30] micmus: ah, no it does not
[11:45:23] micmus: well, OTP sort of already maintains this for you in `Process.get(:"$ancestors")` - but that only works for processes that adhere to the OTP principles - like supervisors, gen_servers, etc.


[13:06:35] micmus: jkva: in general config keys should only be atoms
[13:06:53] micmus: some places where config is used don't enforce this and that's why it sometimes works
[13:10:09] micmus: josevalim: ^ should mix config (or at least the new Config module) enforce only atoms as keys?
[15:51:44] micmus: mariotomo: only some built-in functions and macros that expand to those built-in functions
[15:52:01] micmus: https://hexdocs.pm/elixir/guards.html#list-of-allowed-expressions


[12:25:53] micmus: Ping timeout: 252 seconds


[10:40:13] micmus: josevalim: do new releases always include erts?
[10:49:27] micmus: josevalim: not really. It's just that's the part that makes releases OS-specific. Without it, you could compile on windows and deploy on linux just fine
[10:49:41] micmus: (if you don't have NIFs)
[10:50:11] micmus: As far as I know, everything else in elixir/erlang is fully portable
[10:51:24] micmus: josevalim: a typical phoenix application has usually just one - comeonin
[10:52:04] micmus: unfortunately all tutorials and guides, etc, recommend using it, so we trap users into compiling on same platform
[10:52:24] micmus: oh, does it? I haven't seen it
[10:55:16] micmus: serafeim: you can do this easily today with distillery, if you don't have NIFs. You need to set include_erts: false in the release config and have erlang installed on the target
[10:55:43] micmus: And it should "just work™️"


[19:20:15] micmus: Ping timeout: 252 seconds
[19:44:26] micmus: 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: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:48] micmus: i don't think so


[17:32:37] micmus: i guess the disconnect is with db_connection expecting sockets to work in passive mode, while mint is active-mode only
[17:32:48] micmus: Would it be hard to add passive mode to mint?
[17:34:30] micmus: Another similar situation I saw recently was broadway that does not allow you to maintain state and mint that requires you to maintain state... So it forces adding another process in there. I guess it's not worse than other http libs, just a bit disappointing
[17:36:39] micmus: ericmj: if it's a source. But if you want mint as part of your sink, you have to add another pool & all of that
[17:38:05] micmus: You can't maintain state in the sink and you can't replace the sinks with gen stage
[17:40:28] micmus: I'm not sure it's the only thing, but I think it's the biggest one
[17:45:30] micmus: josevalim: yes, but I can't hold the mint struct in the broadway consumer process. I have to artificially introduce another process to hold the connection and check it in/out for every message
[17:46:48] micmus: Similar if I need other processes for the consumer - I can't just create them when the consumer starts - I have to do some weird lazy-initialization dance and maintain a registry. Lots of unnecessary dance
[17:48:32] micmus: ericmj: sure, I can do all of that with raw gen_stage, but then I have to reimplement all of the things broadway provides. You could argue you could do the same with raw processes ;)
[17:49:06] micmus: ericmj: broadway allows you to inject custom stages as sources, but not as sinks. It forces you to build stateless sinks
[17:50:35] micmus: Sure. I agree. It's just this seems like a weird limitation. I'm not involved with the project so there might be a technical reason this is not allowed, but it's quite limiting in what you can use broadway for
[17:56:36] micmus: ericmj: what if there was an API like `Mint.recv(conn)` that would call the correct recv underneath for you?
[18:00:16] micmus: Right, that makes sense. Though, I think mint internally still calls gen_tcp/ssl, doesn't it? So it would just remove it from one place but not others
[18:05:53] micmus: josevalim: not sure I understand. If the state is for the sink, why do you need to shut down other sinks or producers?
[18:06:47] micmus: and the only place where I want to have state :P
[18:10:47] micmus: You're most probably right. I was just very surprised by this API. It seems like a perfect and natural concurrency boundary, but requires me to split it up again and not leverage it
[18:58:45] micmus: nickjj: the database does the validations, the constraint calls in changeset just inform ecto to transform the database errors into nice changeset errors
[18:59:49] micmus: if anything you'd do that on the db side
[19:00:02] micmus: no idea how, though


[17:45:11] micmus: josevalim: I don't think there is, no. I guess beam_lib:chunks listing all known chunks with the allow missing option could be useful in some cases
[17:49:00] micmus: josevalim: I'm not sure I follow. In general line numbers are embedded as references to the location table inside of the bytecode instructions
[17:56:00] micmus: yeah, you'd probably need to traverse the bytecode for that


[06:48:10] micmus: Read error: Connection reset by peer
[06:48:29] micmus: has joined #elixir-lang
[13:41:03] micmus: serafeim: is this what you're looking for? https://hexdocs.pm/phoenix_html/Phoenix.HTML.Format.html#text_to_html/2
[19:32:36] micmus: starbelly: I think this is a decent resource http://www.craftinginterpreters.com/ - it builds a stack-based VM instead of a register-based one, but the differences between them aren't that huge and stack-based VMs are simpler (you don't need the whole register allocator shebang), so it might be a better learning tool


[12:22:55] micmus: There are. I'm a bit disappointed though, that they all replicate the architecture of the BEAM exactly or as close as possible. I think it would be interesting to explore some different design trade-offs


[09:09:17] micmus: How about something like "only whitespace is allowed after heredoc start" or something along those lines
[10:55:14] micmus: fastfresh: you don't start ranch itself in your supervision tree, you can start listeners in your tree instead of ranch's tree. Ranch is still an application that is started on its own in the "embedded" mode
[11:58:00] micmus: I found one issue with it that the full search does not consider module/function names, because that's already in the autocomplete - but somehow there are more results in the autocomplete that the thing you want is not there
[12:27:25] micmus: benwilson512: AFAIK the elixir browser-testing libraries support that out of the box
[12:28:21] micmus: Ah, that sounds wild to do :P
[16:42:35] micmus: Nicd-: I know there's some code during BEAM startup where it tries to discover processor and memory topology, but I have no idea how it is later used
[22:45:54] micmus: It's nice you can implement NIFs in Rust, but it's even nicer to use ETS that is faster than the rust nif... https://twitter.com/michalmuskala/status/1129518114176155648
[23:01:14] micmus: tristan__: I didn't bench on 22 because the NIF refused to compile on 22 saying it's too new :P


[11:45:12] micmus: Also on OTP 22 the generated reports are much nicer
[14:46:45] micmus: AnimalClatter: I don't think there's any document - the approach is simple - master is for next release, every minor has a branch, so that patches are easy to do and every release has a tag
[14:49:21] micmus: master is 1.9 - since 1.9 wasn't released yet - master is always next release
[14:50:53] micmus: Not necessarily. Master might stay 1.9 until at some point development on 1.10 starts - then a 1.9 branch is forked and master starts tracking 1.10. Though usually nowadays I think it's forked immediately at first rc release


[07:53:49] micmus: gamache: if you haven't found solutions yet, killed usually means some linked process was "brutally terminated" with the untrappable kill reason. It's probably not the only process terminating you'll find in the logs


[08:15:27] micmus: jkva: take a look at how ex_aws works - you split making requests in two parts - you first build a data structure that represents the request - including config, etc. Then you can execute this by passing it to a common request function
[08:15:47] micmus: For me that's very much the preferred way of doing API clients in Elixir
[14:44:17] micmus: josevalim: yeah, the compiler does it in a way that it emits {:literal, _} operands and then they are specially encoded in the beam files. The loader loads them in memory and sets the operands to the real address


[10:15:56] micmus: has joined #elixir-lang


[12:07:15] micmus: nickjj: there's no ecto 4 :P you probably mean 3. AFAIK The ecto.dump and ecto.load tasks always required pg_dump and psql respectively. Also ecto.setup is not a standard task and probably something defined in your project. Last - you don't need libpq, at least not for ecto/postgrex, it implements the tcp protocol from scratch and does not use C bindings
[12:12:16] micmus: nickjj: I don't think anything in there should require pg_dump. pg_dump is only used by the ecto.dump task
[21:43:53] micmus: *.net *.split
[22:07:59] micmus: has joined #elixir-lang


[01:35:34] micmus: Ping timeout: 258 seconds
[01:41:28] micmus: has joined #elixir-lang
[03:23:47] micmus: Ping timeout: 245 seconds
[03:24:25] micmus: has joined #elixir-lang
[07:14:12] micmus: has joined #elixir-lang


[13:50:49] micmus: dysfun: on OTP 21+ you can use the :erlang.is_map_key/2 guard
[13:51:17] micmus: it's not exposed in elixir, but you can call the erlang module directly
[13:51:41] micmus: Elixir still supports OTP releases that don't have it


[12:02:25] micmus: Read error: Connection reset by peer
[12:03:07] micmus: has joined #elixir-lang
[13:35:55] micmus: linduxed: elixir suppresses warnings from the else branch of with because it causes a lot of false positives in more complex scenarios
[14:06:19] micmus: linduxed: it's something else, the elixir compiler adds AST annotations that the code is compiler-generated (which suppresses warnings) - those annotations cannot be represented in the erlang source
[17:46:18] micmus: has joined #elixir-lang


[16:50:54] micmus: gamache: poison 4 stopped working with phoenix & ecto, because it broke the API they used. So using poison in a project with phoenix or ecto you're bound to use old versions only


[10:19:21] micmus: Serafeim: the big difference is that Elixir macros are compile-time only and always have to be explicitly enabled with require/import/use, they can't just "appear" in your code out of nowhere. In practice this limits the "magic" aspect tremendously while retaining most of the flexibility
[10:22:44] micmus: nox: any macro can do whatever, but there's always an explicit path
[10:46:36] micmus: lpil: we have it and it's called :"$handle_undefined_function"/2 :P
[18:47:49] micmus: nageV: it's all tuples. Though depending on some other factors there are other things going on that might make the memory use smaller - if you had literal code like what you showed, it would actually not allocate anything since all values are known at compile-time
[18:48:02] micmus: it's all pointers is what I wanted to say :P
[18:49:24] micmus: nageV: because of those other optimisations structs usually use only 3 + n words and tuples 1 + n, for n elements, so the difference is not that big.
[18:54:39] micmus: yes, though you can update multiple fields at once with maps
[18:54:59] micmus: how are you storing them? ets?
[18:57:14] micmus: hmm... I think ets is unfortunately storing maps without the constant keys optimisation, so it would be 4 + 2n for structs, records should be better
[18:58:20] micmus: nageV: also - have you tried updating them inside ets in place with :ets.update_element? It might not reallocate, but I'm not sure
[19:00:40] micmus: nageV: more or less. The optimisation is more general - any compile-time constant parts of any data structure are allocated just once per module. Since data is immutable, you don't need to copy them. Small maps are implemented conceptually similarly to two tuples - one for keys, one for values - for structs the keys tuple is always constant
[20:35:03] micmus: nageV: almost correct. maps are 2 + n and structs 3 + n - because we don't need to count the keys, but need to count the value of __struct__
[20:35:22] micmus: that is true for maps of up to 32 keys. After that it gets a bit more complex
[20:40:46] micmus: nageV: Now that I think about it I think I was wrong. it's 3 + n for a map and 4 + n for struct:
[20:40:47] micmus: header + size + ptr to keys + n slots
[20:41:43] micmus: no need to count the "top level" pointer, because it's embedded in the parent
[20:45:44] micmus: the header stores size + 2 (so the flat size in heap including size word and keys). And yeah, it could be omitted, but it's not now. It's on my list of things to optimise :P
[20:46:03] micmus: I mean the size word could be omitted


[16:49:52] micmus: *.net *.split


[14:56:24] micmus: nox: you could leverage the zf alias for mapfold and call your function pzf :P


[09:47:39] micmus: has left #RubyOnRails: ()


[11:29:54] micmus: has joined #RubyOnRails
[12:25:50] micmus: *.net *.split
[12:27:29] micmus: has joined #RubyOnRails
[15:01:21] micmus: *.net *.split
[15:03:08] micmus: has joined #RubyOnRails


[11:27:21] micmus: *.net *.split
[11:29:01] micmus: has joined #RubyOnRails
[11:29:01] micmus: Changing host


[13:56:18] micmus: Ping timeout: 240 seconds
[14:00:08] micmus: has joined #RubyOnRails


[19:14:46] micmus: Ping timeout: 264 seconds
[19:46:32] micmus: has joined #RubyOnRails


[06:46:39] micmus: has joined #ruby
[17:09:21] micmus: Ping timeout: 252 seconds