Elixir for Ruby developers: the three most important differences
phoenixonrails.com
phoenixonrails.com
.exs files are compiled just like .ex files are. The only difference between `elixirc` and `elixir` is that the former creates an artifact on disk, and the latter does not. See https://medium.com/@fxn/how-does-elixir-compile-execute-code....
Also, Ruby is as compiled as Elixir is.
Compiled vs interpreted is blurred the moment you compile to bytecode run by a VM. An artifact is not a fundamental difference.
So if you had different behavior for ex and exs that would cause developer confusion.
And it would be the same as in another language if you run a program that has no side effects. For instance "python abc.py" will gladly run a abc.py that is empty or has "class ABC: pass" in it.
This leads to differences such as Ruby meta-programming happening at runtime, Elixir’s at compile time. The Elixir compiler (the Erlang compiler really) can also afford to do more work at compile-time which then leads to different approaches at the JIT level too.
You could also be defining methods pretty much whenever, for instance in response to user input, mutating the state of the process from that call onwards.
The former is much, much more common than the latter.
e. A blurring of the 2 is something like ActiveRecord defining field accessors dynamically once a DB connection is eatablished. You connect to the db and now your User model has email, first_name etc methods, unless you'd defined them already.
I'm guessing nothing quite like this could exist for Ecto(I vaguely know this isn't a super good comparison, Ecto is quite different from AR from what I remember).
That being said even that would still happen as part of a prod app's 'loading' phase so to speak rathet than during a request cycle.
So you are right there are distinct phases but they are established by convention and practices. And sometimes it is different between dev and prod (lazy loading vs eager loading). Or at least it was back then. :)
> I'm guessing nothing quite like this could exist for Ecto
Correct. :)
Thanks for keeping me factual.
However many Class.method names in Ruby's standard library have a match as Module.function in Elixir, by design, to ease the migration of developers. Language developers take note, copy from the language you want to lure developers from.
https://web.archive.org/web/20230000000000*/https://phoenixo...
after the Learn Phoenix Fast red box.
However the convention is to put dates at the beginning of an article. Readers shouldn't have to make an effort to look for them.
This reminds me when I had to look for how to check for inequality in Lua after I wrote != and it didn't work. <> didn't work too.
A lot of the things that are ‘elixir’ are what I learned when I was writing PHP and modding forums.
[1] https://elixir-lang.org/blog/2022/10/05/my-future-with-elixi...
I say you'll be in the docs often because of things like
Enum.map which returns a List not a map
Enum.map_reduce takes either a List or a Map, but returns a List.
Kernel.get_in takes a Map and a List
@ does not work at all the same way in ruby vs elixir, it's not even close
I would probably also put in
"Please for the love of God don't try to turn a genserver into an object"
Because many ruby programmers will try.
But I have been free because the company was broken. I really want to keep writing Elixir, are there any remote job opportunities here?
P.S. I also have some experience of React/Nextjs, Ruby and Scala.
Now, you've got `dbg()` and running whatever you're running via `iex -S <whateveryouweredoinghere>`.
Prior to `dbg()` you had `IEx.pry()`.
Personally, I use it for any web app I'm making. It's a very simple language at its core and is just as good for tiny things as it is for large ones.
The last time I used it seriously, we used Erlang as the high level language for these: https://www.icare-world.com/us/product/icare-eidon/ and it was a great fit for that kind of semi-embedded environment.
A slightly cool thing its enabled is that I have a monolith with a single microservice. All the microservice does is process messages from the main app to process images, upload them to S3, then notify back when it's done. The cool thing is that they can be run on two separate connected BEAM instances communicating via the built-in message passing with no need for an HTTP API. I haven't deployed this, yet, though.
Maybe that's still not what you're looking for but I was really happy when I figured out I could do that :D
Working with it in a real project now, instead of toy examples like in the video, it works really well for when you have highly complex components that rely on quite a lot of local state.
What you'll find is the developer experience is quite nice with LiveSvelte compared to JS hooks.
Little over 3 weeks from `mix new` to the live event. Not sure how I could have done it so easily without OTP and LiveView.
Can you share any details of how that works? E.g. do you operate on a single HLS chunk at a time, or can you get ffmpeg to separate a continuous audio stream, etc?
When a stream starts I start a supervisor that then starts a GenServer to manage the port. On init a port is started for FFmpeg (using the above bash wrapper) with args that sends 16-bit PCM audio back to the port through the `handle_info/2` callback.
When a new live HLS segment is downloaded by FFmpeg the entire segment's audio is sent to the GenServer all at once (could be a few handle_info/2 calls, but it happens quickly). Since I want to work in small fixed chunks, I send the segment's audio to an AudioBuffer GenServer (started as a sibling under the same supervisor). This buffer uses binary pattern matching to segment the audio in chunks exactly 2 seconds long while keeping any remainder in the GenServer's state for the next buffer event. I then send the chunks to another ChunkBuffer GenServer that pops chunks at 2-second intervals for processing.
Since everything is supervised, if (when...) FFmpeg crashes the supervisor just restarts it. Meanwhile, the audio in the buffer is still processing and nothing goes down. There might be a duplicate word or two in the transcription if the restarted port processes a segment again, but everything keeps running smoothly.
For even more reliability, I have the application running clustered across four locations in the US, EMEA, and APAC using libcluster[^2]. The stream supervisor is started under a Horde.DynamicSupervisor[^3] with a custom distribution strategy. The strategy prefers the region closest to the company HQ, but if it goes down, the processes will be restarted in another region.
[^1]: https://hexdocs.pm/elixir/1.13.4/Port.html#module-zombie-ope...
Elixir felt all around like s perfect fit for it , apart that some faster deep mutations likely would have been had to be ported to rust or c because the way I wrote it having 250 players on a single map walking around and seeing each other close by caused huge latency but no crashes Scaled well across multiple machines and lots of players as long as they did not all bog down the same map process :) Didn't even had to think s lot about how I structured it for the current state of development it was basic rapid iteration with mostly live recompilation on changes without having to restart anything https://gitlab.com/zen_core/zen_core
1. receiving an answer from a core contributor (valim, McCord, etc)
2. Having the answer become part of the documentation for the language or library
As an aside, the elixir community has a different didactic approach to many others: the documentation in elixir is genuinely instructive (vs a descriptive reference).
As an example, I've been able to download the elixir, Phoenix, and ecto docs and work on an app entirely offline, on an airplane ride, and never felt like I needed to Google anything.
A common elixir answer to "where are all the blog posts" is "read the docs. No, seriously."
This is indeed very common the forums, ha. Also common is for people to actually then go read the docs and be like, "Oh crazy, I'm not used to this!" Not to over-sell the quality of the docs, of course they aren't perfect but they really are particularly good.
That said, with Ecto I just ask it to give me the SQL query. From there it’s pretty easy to manually write the Ecto equivalent.
3.5 is as you describe. 4 isn't perfect but it's good enough, in my experience.
Oh and the chat is better for me than the API. API sometimes gives me the complete opposite of what the chat (correctly) gives me.
I will take your word for it and try.
The other day I used this to create an Elixir wrapper around, appropriately enough, the OpenAI API.
Of course, there's the option of taking an appropriately licensed open source license and making an internal fork... not expecting to really receive updates from upstream after the point of departure.
I've personally been surprised by a pro of having a more intimate community: in my experience, this leads to a higher signal-to-noise ratio in discussions and resources. It feels like what I need to get online is more "condensed".