28 ms·
With Elixir specifically it was the learning experience I had with Phoenix. I didn't understand how a Phoenix app booted, didn't know where to edit my config. S
by sevenzero 4mo ago
With Elixir specifically it was the learning experience I had with Phoenix. I didn't understand how a Phoenix app booted, didn't know where to edit my config.
Syntax like:
```
socket "/ws/:user_id", MyApp.UserSocket,
websocket: [path: "/project/:project_id"]
```
Elixir gives you too much freedom on how to write something on a syntax level which really annoyed me.
- ch4s3 4mo ago> Elixir gives you too much freedom on how to write something on a syntax level This is true perhaps compared to python or go, but not compared to Java, JS/TS, or some others. > socket "/ws/:user_id", MyApp.UserSocket, websocket: [path: "/project/:project_id"] Socket is a behavior, which is like a trait or interface. MyAppWeb.UserSocket implements the behavior. It's basically a convenience over having to write a bunch of repetitive WS or long poll handling every time you want a socket like thing. Its pretty well documented https://phoenix.hexdocs.pm/Phoenix.Socket.html https://phoenix.hexdocs.pm/Phoenix.Socket.html.
- solid_fuel 4mo agoI love Elixir and Phoenix, but Phoenix especially uses a lot of compile-time macros and it can be a steep learning curve when you need to pull apart the skeleton framework to figure out how things are actually wired. I pretty frequently find myself needing to open up the source to understand what's actually going on, the docs aren't bad but it often feels like they assume a lot of existing familiarity with phoenix. In this example, `socket` is a compile time macro and it's being called with path = "/ws/:user_id" module = MyApp.UserSocket args = [ websocket: [ path: "/project/:project_id" ] ] and what is does is register that data with the `phoenix_sockets` attribute inside the module you called `socket` from. At compile time that gets turned into a lookup inside your module, and presumable then the UserSocket module is invoked when a websocket request hits the specified path. Would you find it more clear if socket was called like this? socket("/ws/:user_id", MyApp.UserSocket, [websocket: [path: "/project/:project_id"]]) Or, alternatively, would it help if the endpoint was more specifically defined like defmodule MyApp.Endpoint do use Phoenix.Endpoint, otp_app: :my_app, web_sockets: [ socket("/ws/:user_id", MyApp.UserSocket, [websocket: [path: "/project/:project_id"]]) ] end
- sevenzero 4mo agoI think the lack of parentheses is whats throwing me off regularly with Elixir.
- solid_fuel 4mo agoI find the optional parentheses, and the way that keyword lists are defined to be the two biggest stumbling blocks when I come back to Elixir after a while way. Coming from other languages, I find that example("with", 3, extra: "arguments", as: "a", keyword: "list") being equivalent to example("with", 3, [extra: "arguments", as: "a", keyword: "list"]) and example "with", 3, extra: "arguments", as: "a", keyword: "list" always takes some extra mental effort to get through, especially when there's no parenthesis. But I appreciate not having to write all the extra brackets and parens when I get going, so I think it's a fair tradeoff.
- arcanemachiner 4mo agoElixir has enough syntax sugar to cause diabetes. Personally, I like the flexibility, but yes there are a lot of rules to keep in mind.
- dqv 4mo agoone more ;) example("with", 3, [{:extra, "arguments"}, {:as, "a"}, {:keyword, "list"}]) iex> [{:extra, "arguments"}, {:as, "a"}, {:keyword, "list"}] = [extra: "arguments", as: "a", keyword: "list"] [extra: "arguments", as: "a", keyword: "list"]