With do(:)?

As I said, in this cases you really should prefer to use do ... end, it will make the code much more readable. Also do ... end is recognized by most IDEs as markers for code-folding/hiding wheras parenthesis are not.

Code-folding/hiding is actually the mainreason why I do avoid short-form-do for anything that is more than a single function call in the body (rule of a thumb). As soon as I start to pipe, or to nest function calls I used do ... end, since it will end up on multiple lines anyway.

Another magical barrier I try not to breach is a line-width of 120 characters.

1 Like

Yeh all good points

  • I suppose I prefer the short form syntax in order to enforce fewer imperative statements and more expression-only functions…

But as with anything (and as you point out) perhaps this is an exceptional case and better not - ‘with do’ is perhaps more on the imperative statement side of things in any case…

I would say a lot of features implemented with macros tend to feel more on the imperative side.

That being said the with is a special form which to me feels more like a “code organization device” (a stripped down implementation of Either) rather than a “language feature”. Also none of your examples deal with the else explicitly (just because you don’t see it doesn’t mean it’s not there).

The “code organization nature” seems to be even more pronounced when it’s used with action_callback in a Phoenix controller.

1 Like

As has been talked about elsewhere, do is not imperative, it is merely sequential. Elixir does not support imperative programming. There’s plenty of precedent for this, haskell also uses do notation to notate sequential operations.

2 Likes

What’s the diff between imperative and sequential operations?

Perhaps I am mixed up.

Tbh, I would say Haskell’s ‘do’ is also imperative. Haskell is usually lazy and you need a special case ‘do’ syntax do do things eagerly / sequentially…

I am open to being educated here : )

Jose articulated this very well here: Why is the word do used to start blocks?

2 Likes

V good.

Elixir doesn’t do single assignment (sometimes makes things look like things are mutable which I am not a fan of, prefer Erlang) and you can sprinkle functions with side-effects.

So, in the strictest sense, I think he’s wrong. But in every day use and most of all - the spirit of the language - he is of course totally correct (I am a big fan of this language).

Upshot, I’ll still bias towards using ‘do:’ style functions where it makes sense, trying to reduce complexity and sequential code.

Thanks for the link - good food for thought.

1 Like

Which proposition is wrong? Nobody is arguing that do end excludes side effects. Rather we’re merely arguing that what do end means is sequential code. That code may have side effects, or it may be pure.

This is in contrast to say a C style for loop which by its very nature implies mutation. C style for loops are a classic example of imperative programming. do end has no such intrinsic characteristics.

2 Likes

This is actually an Erlang (practicality) thing - in a sense Elixir’s do..end simply replaces Erlang’s punctuation:

A clause body consists of a sequence of expressions separated by comma (,):

1 Like

Imperative programming is often associated to mutation and side-effects. You need to tell the computer where to store that value or to change its state.

i) Lack of single assignment, means sometimes when i look at Elixir code it looks imperative. I know behind the scene it is not, but I just don’t like looking at it.

ii) Side effects are a necessity in Elixir

I suppose it depends on what you’re used to. When you used to purer languages you think Elixir can sometimes look imperative. When you are used to Ruby you think it looks less imperative.

All in all, I like the balance struck by Elixir (altho hanker for single assignment ; )

Not the only one, it feels ‘wrong’ coming from Erlang. ^.^;

Exactly, the punctuation is a series, a single expression, a block does not feel like a single expression. That is one of the reasons I wish erlang had a scoped let, sure it does the same as , but it is more explicit about initialization and usage of a binding, easier to search and grok for. Something in Erlang like a=21,a*2 is just parsed like a normal operator, it is a single expression parsed like ((a=21),(a*2)) where the , operator just evaluates the left, uses the new output environment as the input environment when it then evaluates the right, returning the result of the right environment, it is clear and obvious. :slight_smile:

I think exactly this. It seems you and I both came from stronger languages than languages like Ruby (I came from over 10 years of erlang and a whole-lot of C++ for over 2 decades prior, of which I even tried to write functionally in it as well). To be honest, it is Mix and the Macro’s that keep me using Elixir, without those it does not seem to gain anything over Erlang (or lfe, which also has strong macro’s, even stronger perhaps than Elixir, however it does not have the ecosystem supporting it). ^.^;

I really like Erlang to be honest, even its little droppings of , and ; all over the place, they make sense to me. ^.^

3 Likes

:grinning:

Compare the code in Elixir in Action and Programming Elixir - I think you’ll be able to tell who’s coming from a Ruby background and who’s coming from an Erlang background (and which one feels “more functional”).

4 Likes

No love for protocols? Strings? Structs? :slight_smile: For some reason I rate protocols > macros.

1 Like

True! The String handling in Elixir is top-notch! Fixed all the UTF8 horror I dealt with in Erlang!

Structs are interesting, but I’m too used to records, they seem like a decorated map to me just like records decorated tuples, except that it is easy enough to pattern match on the :__struct__ key as it is. ^.^

Protocols are single-dispatch, they have great uses, like the inspection protocol and such, but I would love a multi-dispatch version of them (*hint*hint*). ^.^

Honestly I’d think protocols could be generalized out to a multi-dispatch pretty easily.

Though to be entirely honest, I’d love it if the language was typed, protocols would be useless then as you could just have auto-witness dispatching with no run-time cost. ^.^
That would probably be a new language though. :slight_smile:

But yeah, I forget about Strings, they are awesome. I’m still in my Erlang and C++ habit of *DO*NOT*TOUCH* unicode, I just read it from files (translations and such based on keys read in to ETS and so forth) and just do simple moving around of data without actually transforming it. I still do not even, say, do something as ‘simple’ as upper-case strings in my applications due to how strongly this has been ingrained in to me. ^.^;

/me rates macros > protocols for sure though

1 Like

Of course, Elixir’s most magnificent feature is the &foo(&1,bar) shorthand function syntax :smile:!

1 Like

pipe is handy too…

1 Like

I really, really miss that in Erlang…

That’s not quite true. Protocols are about open ad-hoc polymorphism and types do not necessarily give you that. The point of protocols is exactly that the call-site may not know where the implementation is at compile-time so runtime work needs to be performed (unless of course you recompile the whole project once new implementations are added, similar to protocol consolidation, although that impacts incremental compilation).

1 Like

I just wish I could write &foo(bar).

2 Likes

Seriously?

While it may be a welcome addition to the toolbox, I always felt that the pipe was “a poor man’s path” to the effect of function composition - now granted it does have a nice way of dealing with those pesky extra parameters.

And even though Erlang doesn’t support function composition out of the box, how hard is:

-spec compose(F,F) -> F when F :: fun((T) -> (T)), T :: any().
compose(F,G) ->
    fun(X) -> G(F(X)) end.

Using partial application (via closures) you can DIY a function pipeline of any complexity to your heart’s content.

Heck, you can even practice all this in JavaScript!

I’m constantly amazed how often it takes syntactic sugar to convince some people to adopt beneficial practices (apparently if it’s a little more work/more boilerplate it’s simply not worth practicing).

3 Likes