muhajirframe
defmodule LousyCalculator do
@spec add(number, number) :: {number, String.t}
def add(x, y), do: {x + y, "You need a calculator to do that?!"}
@spec multiply(number, number) :: {number, String.t}
def multiply(x, y), do: {x * y, "Jeez, come on!"}
end
What i can see is the def doesnt have end there. If it is optional, is it a good practice? Thanks
Trending in Questions
Hey guys,
I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly
Do you guys have any suggestions what is the best prac...
New
Hello!
Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app.
I creat...
New
I have what I’ve heard referred to as a “lookup table” in my database. This is a way of assigning codes to common values. One common lo...
New
Hello,
I’m developing a online persistent chat system (what’s app) like using elixir/dynamodb/aws for a mobile app(flutter).
The diffic...
New
What approach to take when sending live updates to “random” users Hi! I have a question, I have a little chat app, and when I create a DM...
New
Anyone here using Honeybadger?
My Honeybadger account is being overwhelmed with noise from some bots. Seeing a lot of
Bandit.HTTPError...
New
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
Other Trending Topics
Hologram: The Journey to Local-First Elixir in the Browser - Bart Blast | ElixirConf EU 2026
https://www.youtube.com/watch?v=qqpNovT7cys...
New
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
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
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
There are three potential reasons for members of this forum to have a look at https://vutuv.de
You are tired or annoyed of LinkedIn.
Yo...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixir-ls
- #ai
- #elixirconf-us
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
NobbZ
No, the
endis not optional! When you usedo, you have to useend, you can use one-line-syntax though, then you have to replacedo foo() endwith, do: foo. Be aware of the comma and the colon!Also please try to avoid putting screenshots your posts, when copy-pasting the code and linking to the source is also possible. Some users knowing an answer to your question might be unable to view pictures in general or temporarily (I’m often on a mobile connection and strip many images to save up bandwith).
rockwood
Thanks for your question @muhajirframe.
defanddefphave two forms:Normal:
Inline (note the
,and:):When defining multiple function heads, the inline form can make it easier to visually read what arguments are being pattern matched. Typically the inline form should be used when the function body is short.
Either way, both forms are valid and you can use them interchangeably.
NobbZ
This behaviour is not related to
defanddefpin any way. It does apply anywhere where you can pass in adoblock.defmodule,defmacro,if, or even your own macros and functions. A very similar thing does work forelseas well.rockwood
Absolutely correct. The original question was specifically asking about
defanddefpso I just wanted to make things as clear as possible.kylethebaker
Just to elaborate further on what’s already been mentioned:
A
do/endblock is really just a keyword list under the hood, with adokey and some expression as the value. You can read a little more about it here. In other wordscan also be represented as
defanddefpare just macros, so although they look a lot like keywords they are really just calls and therefore have the same characteristics as any other function/macro call with regards to syntax. They have an arity of two: the first argument is the call and the second is the expression. Another way to write a function definition could be:When written this way it’s no longer ‘disguised’ as a keyword. It’s clear that it is just a macro call. Since parenthesis are optional for calls we can also use the form:
And since the brackets on keyword lists are optional when used as the last parameter in a function call, we can also use this form:
And now we’ve arrived at the ‘single-line’ form. Its clearer now why the comma and colon come into play. It isn’t a special syntax used for single line function definitions: the comma is just the parameter separator used in all function calls and the colon is for the key in the keyword list.
Finally, we can represent the
dokeyword list using thedo/endblock syntax and get:When using a
do/endblock as the the final argument in a function we can omit the leading comma (I’m not sure if I’ve ever seen this formally stated before, but it does seem to behave that way).This same behavior applies for all other macros. For example,
ifis also a macro, so you can break it down the same way:An
elseblock (as well as try, catch, rescue, and a few others) is really just another key on thedokeyword list, so in other words you can introduce theelseblock the same way:To summarize:
defanddefpare just macros calls, and as such follow the same syntax rules as other calls. Technically there aren’t two separate forms for function definitions, there are just varying degrees of sugar you can use to dress up function calls. That being said, you will encounter these two ‘forms’ enough in practice that it makes sense to distinguish them, so while there aren’t technically two forms I think most people will recognize them as being the two de-facto forms.The single-line variant is used often, here are some sections from an elixir style-guide to give you an idea of when to use them vs the block variant: GitHub - christopheradams/elixir_style_guide: A community driven style guide for Elixir · GitHub
Edit: There is also another bit of sugar that I left off in these examples. Keyword lists are really lists of 2-value tuples in the form
{atom key, mixed value}. So for example:is really
Which makes the
ifexample become in full:It can be a little bit overwhelming and puzzling at first having to deal with these little syntactic intricacies. My first reaction to seeing the single line
defform was “why is that comma there?! and why a colon too?!”. I thought having all these different layers of optional syntax was bizarre, and personally I would prefer there to be less ways to write something, not more.I was initially turned off by it until I realized that most of what I considered to be language keywords were actually just macros. Then it started to make sense why some of these syntax choices were made (at least why I think they were made): they give you the ability to make macros that look identical to traditional keywords. This is why you can’t tell that
defis really just a macro until you squint and peel back the layers.Having this capability allows you to expand the language to add expressive, domain specific constructs. Phoenix has several great examples of this, like defining plug pipelines, route scopes, things like attaching plugs directly to a controller, etc. Ecto’s query DSL is another awesome example, same with ExUnit’s assertion and test definitions. Some of these constructs feel so natural and expressive that they feel like they are a part of the language itself, but they are actually more like libraries.
Anyways, I think it is awesome. I may have gotten a little bit carried a way here, but hopefully I’ve helped in some way.
notriddle
https://hexdocs.pm/elixir/master/syntax-reference.html
ethanvaughn
So, the
endIS optional?hauleth
No, it is not optional. There are 2 ways of writing body of function - as
do-block (and then you need to useend) and as keyword listdo: foo.do-block is a sugar for another one, but these are separate constructs.iamahmed
It isn’t optional, but there’s a special syntax in which its not required.
i.e. def foo(), do: --some code here–
eksperimental
This made me think what tokens are optional in Elixir’ s syntax, and the only thing that I could come up with were:
Anybody can think of anything else?