krp

krp

After a year with Elixir I grew tired of writing, reading, and thinking in long, core function calls that I used to the point they felt like boiler plate. This is not Elixir specific, but here it seems easy to create a solution. Recently, I’ve been making modules and functions with abbreviated names (often single letters) for core functions or slight modifications of them.

For example, from my module S

def s(string, splitter), do: String.split(string, splitter)`
def st(string), do: String.split(string, "\t")

Today I learned about defdelegate which would work for the straight alias S.s, but not for creating something like S.st. This has me asking a few questions.

  1. What are the advantages of using a macro to generate an “alias” like those described. In my readings it seems that creation of a DSL is benefits from macros. I seem to have missed why macros are preferred over functions (I’m sure this is basic) ?
  2. Without digging in and picking it apart, I can’t follow exactly what is happening in defdelgate. Other than creating an alias function what is going on ?
  3. Off the topic of Elixir, but related to abbreviated module/functions names: Are there any languages other than MUMPS that have these built in?

Thanks to all.

Showing Posts 1 to 5

kip

kip

ex_cldr Core Team

Some thoughts:

  1. defdelegate/2 can define delegates for both S.s/2 and S.st/1 - unless I’ve missed something else in your expectations?

  2. defdelegatge/2 is just creating a function that calls the target function. Its a macro so that interpreting the arguments is done once at compile time and not every time at runtime.

gregvaughn

gregvaughn

What you’re doing is optimizing your code for writing at the expense of reading, but most code is read many more times than it is written, so it’s a bad tradeoff in the long term. I would not want to join your team and have to maintain this code you’ve written.

In order to optimize writing speed, you should look into custom snippets in your editor of choice. If your current editor can’t do that, then switch to one that does and you’ll be able to train your finger muscle memory and reuse that for any language you write.

That being said, I do have a utility module in my work codebase that offers shortcuts to look up our core domain entities. We don’t go so far as single letter function names, and this is not used by business logic itself. It’s useful for troubleshooting in iex.

Exadra37

Exadra37

I totally second this.

One of the things that really pisses me off in Software Development is when I have to read code that uses abbreviations, because it’s not readable, I need to lookup what all that abbreviations mean each time I read the code. It’s just a pure waste of my time and energy.

In my opinion code should just look as much as possible as reading a book.

So, I have a question for you:

How you gonna track in your memory all this short-names when you arrive to a lot of them, like more then 20/50/100 or whatever is the limit for your brain to memorize them?

krp

krp OP

Happy New Year kip and thanks for engaging

Regarding #1 I am able to get S.sn to work using defdelegate if I add a “dummy” variable with a default
iex(1)> defmodule S do
...(1)> defdelegate sn(text, spl \\\ "\n"), to: String, as: :split
...(1)> end
iex(2)> S.sn("foo\nbar")
[“foo”, “bar”]`

However, that seems a bit cloogey. What I would prefer to do is

iex(3)> defmodule S do
...(3)> defdelegate sn(text, "\n"), to: String, as: :split
...(3)> end
** (ArgumentError) defdelegate/2 only accepts function parameters, got: "\n"...

Regarding #2
That was my assumption, but when I benchmarked the aliasing functions above vs using a macro I saw no significant difference. However, just now as I’ve been writing, it occurs to me that benchee likely compiles each test prior to running.

Perhaps I should write a modified defdelegate. Grokking the original would be good in itself.

Thanks again and all my best.

krp

krp OP

Happy New Year Greg and exadra37. Thank you for your replies. They are clearly thoughtful.

I was hesitant to even begin to go down this path. Your points were all ones I considered and frankly fretted over. In the past I’ve run groups where I was dogmatic about explicitness. Finally I felt comfortable based on the following

  1. I (or anyone worth their salt) could throw together a script to expand my abbreviated forms to the originals in short order if it was ever necessary. Given my domain that is unlikely and once I have the macro discussed with kip it should be even simpler.

  2. My editor allows me to view associated @doc fields with a simple mouse over of the function. So if in the rare case I question what S.st or S.sn etc mean it is right there.

  3. Most importantly, I saw that the core functions were acting as a barrier for my reading and thinking about code. String.split(term, "\t") seems to require more of my brain than S.st(term) and certainly more than |> S.st

For example
iex(1)> S.r("foo_x", "_x") |> S.c()
"Foo"

rather than

iex(1)> String.replace("foo_x", "_x", "")
|> Macro.camelize()
"Foo"

The majority of the second is essentially boiler plate. In the first what makes this code different stands out. I am also taking advantage of having a S.r/2 that blanks what is being replaced. Perhaps best of all I was able to forget that for some reason camelize is Macro.camelize in elixir

Mnemonics: The first letter is that of the core module. The second is usually for the function. Additional ones tend to be for specific uses of the function. Also I’ve worked to be consistent so that S.st and E.jt are split by and join by tab, respectively. Currently I have ~125. A few I’ve deprecated as capricious as I don’t use them enough to remember them.

In the end it likely comes down to domain. If I were running a group that needed to slot in elixir programmers with no additional training, or was writing for a client that needed the same, this would likely be another discussion.

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New
ryanwinchester
apply_graft/2 doesn’t rewrite an add_many sub-workflow’s deps on an add step. Grafted jobs cancel with “upstream job was deleted” Version...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews