spencer.christensen

spencer.christensen

I’m going through Tate and DeBenedetto’s Programming Phoenix LiveView and observed the code below.

  defp assign_chart_svg(%{assigns: %{chart: chart}} = socket) do
    socket
    |> assign(:chart_svg, render_bar_chart(chart, title(), subtitle(), x_axis(), y_axis()))
  end

  defp title do
    "Product Ratings"
  end

  defp subtitle do
    "Average star ratings per product"
  end

  defp x_axis do
    "products"
  end

  defp y_axis do
    "stars"
  end

As somebody new to functional programming, I’m wondering whether this granular-level of function definitions is typical? I can see some options:

  • it is idiomatic and a best practice to wrap strings in a function.
  • it is only a best practice to wrap a string in a function when the function name can clarify the purpose of the string (“stars” is not as descriptive as y_axis)
  • it is unusual and is likely being done to account for some sort of future abstraction that relies on a callback of said functions

I’m not arguing for or against anything, just curious for best-practices and idiomatic Elixir use of string binaries. Thanks!

Showing Posts 1 to 5

mindok

mindok

Probably a more common alternative in Elixir would be to use module attributes. e.g.:

@title "Product Ratings"
@subtitle "Average star ratings per product"
@x_axis "products"
@y_axis "stars"

  defp assign_chart_svg(%{assigns: %{chart: chart}} = socket) do
    socket
    |> assign(:chart_svg, render_bar_chart(chart, @title, @subtitle, @x_axis, @y_axis))
  end
mindok

mindok

…However, module attributes are private to a module, so to expose them to other modules you would need to use a public function, e.g.

@title "Product Ratings"
@subtitle "Average star ratings per product"
@x_axis "products"
@y_axis "stars"

  defp assign_chart_svg(%{assigns: %{chart: chart}} = socket) do
    socket
    |> assign(:chart_svg, render_bar_chart(chart, @title, @subtitle, @x_axis, @y_axis))
  end

  def the_same_title_we_use_everywhere(), do: @title # or "Product Ratings"
sodapopcan

sodapopcan

Ya, what @mindok said. I have have barely read any of that book so maybe there are going somewhere with it and will flesh it out later? Wrapping strings in functions as a general rule certainly isn’t a “thing” though. I’ve never done it and this is the first time I’ve seen code that does it (I’ve been doing Elixir for around 5 years).

From what I have read of the book, though, they do extract far more than I personally care to. There are lots of small single-user private functions that don’t really read any better than the bare code in my view. I’m not implying the book is bad by any means (how could I know? …and all of Sophie’s stuff I have read and watched is amazing) and while idiomatic Elixir is certainly a thing, it’s not super obsessive and people have varying styles.

EDIT: One reason I can think of to use functions is that heex overloads @ to access assigns. So if you have

@title "Product Ratings"

def assign_thing(socket) do
  assign(socket, :title, @title)
end

def render(assigns) do
  ~H"""
  <%= @title %>
  """
end

That reads super confusingly because the @title in the render function is referring to :title in the socket, not the module attribute @title.

That’s total guess, though.

al2o3cr

al2o3cr

render_bar_chart(chart, title(), subtitle(), x_axis(), y_axis()))

IMO this would be clearer as a function that took chart and a keyword list:

render_bar_chart(chart, title: "Product Ratings", subtitle: "...", etc etc)

That avoids the confusion of “what the heck ARE all these unnamed literal positional args” while not spamming private functions.

christhekeele

christhekeele

This is correct—it is a conceit they are using to keep the examples focused to the “lesson” at hand: learning Liveview; and to leave “room to grow” the examples with later functionality.

@mindok’s posts concerning module attributes are the idiomatic approach to this! But you can see why introducing those patterns don’t serve what is being taught: instructive writing can be weird like that sometimes.

— All posts loaded —

Where Next? Top

Trending in Questions Top

stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New
water
I’m aware of 2 such projects, are there others? git: GitHub - team-alembic/realworld: A fullstack Phoenix LiveView application with back...
New
itzmidinesh
Hi all, I’m working on a Phoenix project where I need to make external HTTP requests and I’m trying to choose between Req and HTTPoison....
New
pragdave
How do I tell Hologram not to escape HTML when substituting into templates? {Textile.render(@product.long_description)} escapes the HTM...
New
rlipscombe
I’d like to create a file with 600 permissions (rw-------), but there’s a race condition if I create it and then change the permissions. ...
New
leoschweizer
Hi, we run different LLM models across a cluster, with each node loading a configurable subset. Model-specific queues let nodes consume ...
New
rlipscombe
When I use Mix.install with a git dependency, using git@github.com:... how do I change the SSH identity used? I’ve got two Github accoun...
New

Other Trending Topics Top

dominicletz
Hey there, I haven’t seen a list of useful Elixir specific skills for the popular AI tools yet so I’m starting one here with my first. ...
New
raa-ziq
Hi everyone :waving_hand: I wanted to share something I’ve been building — NowBlind, a random chat app designed to help people discover ...
New
mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
OndrejValenta
(I just needed to vent somewhere and LinkedIn is full of hope, or hype, I’m not sure which exactly) AI dream has many faces, but general...
New
kip
Localize is the next generation localisation library for Elixir. Think of it as ex_cldr version 3.0. The first version will be released ...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews