KristerV

KristerV

i’ve recently gotten annoyed at having to jump between files just to check what that function i’m using will return. VS Code could be of help by using @spec, but frankly that too is pretty dense to read.

i would like this Elixir syntax

%MyStruct{} = my_var = Module.some_function()

to be easily readable like this

MyStruct my_var = Module.some_function()

this is just a readability thing. imagining a large function full of this kind of rows i’d much prefer tha latter syntax. it should reduce load on memory by a lot.

before i jump in to learn macros just to create this thing, i thought i’d ask you guys - is this approach a bad idea? is there something out there already? is there a better approach completely?

Showing Posts 1 to 8

hst337

hst337

First of all, this is pretty hard to do with macros. You’ll need to create context-aware AST traversal function to do this right.

Second, just learn to read specs, they’re not that hard to read, to be honest.

It depends on what you want to achieve. I guess that you’re saying something like “I used to work with static typing, and I’d like to have this in Elixir”, but this is generally a bad approach, since Elixir is dynamically typed language by design.

So, there are a lot of different ways to achieve what you want with dynamic typing. If you want to find errors and typos during development, you can use dialyzer which has integrations with every editor. If you want to find errors at compile-time, you can use dialyzer, gradualizer, eqwalizer, etc and you can write unit-tests of course.

KristerV

KristerV OP

thanks for the answer, but i think you’re missing my point a bit. i’m not trying to create bug free code (which i am totally looking into atm so thanks for suggestions on those, just not what this topic is about), i’m trying to increase readability and reduce memory load.

huh? as far as i can see i just need to rewrite MyStruct my_var = to %MyStruct{} = my_var =, shouldn’t be too hard to reorder some keywords, or what am i missing? yeah i know nothing of macros yet, not sure what you mean by context.

i can read specs easily, that’s not the issue. it takes time, brainpower and memory. probably more for me than others since i have an exceptionally bad memory. i forget the type right after i close the file i was reading it from.

i’ve actually worked with typed languages very little and i’m not a fan. however there are some benefits. like less mental load (in certain situations). this is what i’m trying to achieve.

again, not the topic, but haven’t heard of gradualizer and eqwalizer. i’ll check these out.

LostKobrakai

LostKobrakai

There’s two parts to this. There’s the elixir parser, which requires you to write correct elixir syntax. Otherwise it cannot parse the code. Once the code is parsed by the parser (into AST) macros can come in and change their input AST – could be code blowing up when trying to be executed – to some different output AST – which hopefully runs just fine when executed.

MyStruct my_var = isn’t valid elixir syntax – quote do: MyStruct my_var = 1 doesn’t succeed, so there’s nothing a macro could do here.

Not really sure why you’d like this to change the syntax here. If you want the structs be listed why not write %MyStruct{} = my_var = …? That just works and can even help out editor autocomplete.

lucaong

lucaong

As far as I can see, as @LostKobrakai said, this cannot be achieved with macros, because it is not valid Elixir syntax. You would have to build a transpiler, but that’s a totally different kind of problem.

I’d suggest using one of the typing solutions proposed. The issue is mostly about familiarity, and it will soon become second nature if you use it a lot.

My personal view is that a syntax like MyStruct my_var = Module.some_function() would lead people to (erroneously) assume that this is a static type check, while %MyStruct{} = ... makes it clear this is a pattern match, which usually is amongst the first concepts learned when approaching Elixir. In fact, in many cases, when needing to access fields in the struct, one would directly do %MyStruct{ my_field: x } = ....

In other words, there is a trade off between ergonomics and consistency/parsimony of the syntax. Some alternative way to express the same construct more concisely might save some keystrokes, but it adds to the cognitive load of having to understand different ways to express the same thing.

gregvaughn

gregvaughn

You might find the built in jinterface package could help meet your needs :smirk:

KristerV

KristerV OP

oh. okay. i guess i misunderstood the whole thing.

it’s just a hassle to write every time. i don’t find autocomplete very helpful. it jumps in sometimes only.

if we were discussing changing the elixir syntac, then yeah, i’d agree. but since we’re talking package, then it’s not a problem. like i like using shorter_maps. doesn’t lead to any problems.

not sure what this is.


all in all i guess i’m going to try out the explicit syntax and see where i end up. atm i feel like it’s noisy and i may end up avoiding it and thus not having a solution at all.

aglassman

aglassman

I think you will see over time that there are very few scenarios where this is syntax you would really write. In most cases, you will be invoking these functions, and evaluating them as part of a with or case clause. The %MyStruct{} = my_var = foo() pattern is not necessary. This pattern match will raise a MatchError only if the result of foo() is not a MyStruct struct.

In most real use scenarios, you’re going to want to do some more detailed matching, and probably have an execution path in case that match fails. So more realistic scenarios will look more like this:

case foo() do
 %MyStruct{val: x} when x < 0 ->
   "Value is less than zero"

 _ ->
    "No value found"
end

or

with %MyStruct{} = ms <- foo() do
  OtherModule.process(ms)
else
   result ->
      Logger.error("foo() did not return valid results: #{inspect(result)}.")
end

I agree though that IDEs can be very flaky about actually showing the correct spec / docs in editor. I have many issues with this in IntelliJ, so typically just do a split panel setup with references on the on one half. I miss the robustness of JVM docs / autocomplete.

KristerV

KristerV OP

in business logic you’re right. but in views i often just query the db and go with whatever there is and if something goes wrong an exception is a valid response.

in any case i happened on an AST tutorial and now I understand why this syntax doesn’t make sense. and also since the gradual typing research is actually moving then in the long run i think it’s okay to wait for whatever that is and then think about this whole thing again.

so for now %ThisSyntax{} = will_have_to_do =.

thanks for thinking with me everyone!

— All posts loaded —

Where Next? Top

Trending in Discussions Top

AstonJ
As the title says, please share what you’ve been up to with Elixir. Whether that’s been learning it, looking into it, making stuff with i...
2977 91898 914
New
AstonJ
The obligatory hello world thread! Who are you and where are you from? :stuck_out_tongue:
4616 55835 594
New
byu
@chrismccord : I just saw the Extract AGENTS.md from Phoenix.new into phx.new generator commit to the phoenix project. My initial shotgu...
New
arcanemachine
I was working on an Ecto migration and I needed a timestamp. So, for the nth time, I looked up the different data types for timestamps, a...
New
alexslade
Fly’s CEO posted this recently - Turn And Face The Strange · The Fly Blog It says that Fly is going all-in on sprites, which is a worry ...
New
Herve37
We’re evaluating API mocking tools for OpenAPI-based projects and would love to hear what other teams are using. We’re particularly inte...
New
matt-savvy
Is there a word for the ~> symbol used in Version strings? Do you also just call it a Squiggle Arrow™ ?!
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
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
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews