[HN Gopher] Elixir for Humans Who Know Python
___________________________________________________________________
Elixir for Humans Who Know Python
Author : EntICOnc
Score : 253 points
Date : 2023-02-25 07:16 UTC (15 hours ago)
(HTM) web link (hibox.live)
(TXT) w3m dump (hibox.live)
| l_theanine wrote:
| LiveView can't handle spotty connections, I thought?
|
| Career python expert, not huge into Django/we dev in general...
|
| I thought the whole thing with most HTML over the wire is that
| its tied to the connection latency? Unless there's some js
| component underlying the Elixir code that I don't know or don't
| understand.
|
| With the advent of things like flask+html, I find it a little
| hard to believe that Elixir hackers could whip up a MVP faster
| than I've seen it done with flask.
|
| I'm not opposed to functional programming by any means, but just
| because the language embraces it doesn't qualify all the
| constituent frameworks to replace world-class solutions like
| Django.
| freedomben wrote:
| > _LiveView can't handle spotty connections, I thought?_
|
| LiveView handles it just fine. If the websocket disconnects for
| some reason it will automatically re-establish itself when the
| connection is restored.
|
| You can also use the built-in JS module to do client-side
| things when you don't need backend support. I use Alpine.js
| (PETAL stack) and I like it a lot.
|
| If you have a very complex client-side need, it's also pretty
| easy to use React.js for that.
|
| > _With the advent of things like flask+html, I find it a
| little hard to believe that Elixir hackers could whip up a MVP
| faster than I've seen it done with flask._
|
| You'll have to get more specific if you want an accurate
| answer. Does this MVP require a database? Does it require
| specific UI or can you just massage the OOtB UI that Phoenix
| gives you? You'd be surprised at how much of a headstart the
| generators can provide. I've built working protoypes (with
| database persistence) in 30 minutes. If it's purely a static
| page, I would just use nginx directly but you could easily do
| that in Phoenix as well in about the time it takes you to write
| the HTML since the default new project comes with a page
| controller already set up for that.
| enraged_camel wrote:
| >> LiveView handles it just fine. If the websocket
| disconnects for some reason it will automatically re-
| establish itself when the connection is restored.
|
| What the parent means is that, because state is kept on the
| server with LiveView, and events that change that state are
| processed by the server, if your connection is lost, then you
| may find that even basic things, such as having a dialog open
| when you click a button, stop working. This means that
| unstable connections result in very poor UX.
|
| This is in direct contrast to a typical SPA for example,
| where the browser keeps and handles most front-end state, and
| talks to the server only when it needs to (e.g. form
| submission).
| bostonvaulter2 wrote:
| You also might see full page refreshes when the heartbeat
| fails which can be very annoying.
| revskill wrote:
| I guess for 80% of useful use case, Javascript and NodeJS can do
| the job.
| jnsaff2 wrote:
| They wrote there that they were looking at Elixir because they
| did not like the direction Python had taken. I'm sure Python
| can do the same as JS but Elixir is just so much nicer. Which
| is also my experience.
|
| Your point obviously stands, pretty much all of mentioned can
| do the job.
| PYTHONDJANGO wrote:
| Is your comment based on experience with Elixir? How long did
| you work with Elixir professionally?
|
| I guess you have some fundamental experience with Elixir, as
| you would not post some comment here if not?
| revskill wrote:
| Yes, that's the point.
|
| Seriously i will not choose JS today if i have.a very
| specific requirements for choosing Elixir or Python (or any
| other stacks here).
|
| In reality, people choose the stack they're get used to. But
| it's their limited ability to see JS strength to solve their
| issue in first place. It's not informed choice.
| mikedelago wrote:
| At the very end of the day, I think some people just don't
| like JavaScript.
|
| At the risk of speaking for people other than myself, a lot
| of people don't want to write code in JS and if they don't
| have to, they won't. Frameworks/tools like Phoenix and HTMX
| or the fact that many languages can compile to
| javascript/wasm mirrors this opinion
| conradfr wrote:
| As someone who dislike the forced asynchronous nature of Node I
| would say Elixir is a better Node than Node ;)
|
| Most languages can do "80% of use cases" anyway.
| calo_star wrote:
| One thing I love about Elixir's syntax is that virtually
| everything is a call, take the if statement: if
| condition do IO.puts "true" :yes else
| IO.puts "false" :no end
|
| is just a call to the *Kernel.if/2* macro:
| if(true, do: (IO.puts("true"); :yes), else: (IO.puts("false");
| :no))
|
| I was joyous when I realized I could pipe stuff into a case
| statement.
| plainOldText wrote:
| I've been programming my web projects exclusively in Elixir for
| the last few years and I've been deeply enjoying the language.
|
| Although at first, some unfamiliar design decisions annoyed me,
| for they were not well explained in the tutorials I was learning
| the language from - e.g `arg: value` as a shortcut for `[{:arg,
| value}]` in function arguments and other places - over time, I've
| grown to love and appreciate the language and I now more or less
| regard it as an elegant programming language put together by a
| thoughtful person with great programming taste.
|
| The Phoenix framework is a great bonus point if you want
| increased productivity for writing web apps. I don't miss Python
| at all.
|
| Elixir rests on the shoulders of giants though, and the
| Erlang/OTP is yet another elegantly engineered piece of
| technology, enabling one to develop concurrent, distributed and
| fault tolerant systems with ease, and in this regard I think the
| Erlang/Elixir ecosystem takes the crown. The actor model is
| simple, yet very powerful.
|
| For reference, I've also been learning Nim and F#, and they're
| also pretty unique and well designed languages in their own ways.
| I love Nim's fast compilation times, efficiency and
| expressiveness and F#'s powerful type system which enables one to
| develop domain models with ease. I've also been occasionally
| taking stabs at Rust, but it always feels just a tad too complex
| for my brain. I'll continue playing with it though, maybe it will
| eventually make sense.
|
| Ultimately, every design decision is also a tradeoff. I don't
| think we'll ever have a perfect, human designed language.
|
| My dream language would probably be a combination of Elixir and
| F# though, a language with an advanced and powerful type system,
| functional programming and the actor model as the building
| blocks. I guess fast compilation times a la Nim wouldn't hurt
| either. :)
| mdm12 wrote:
| Sounds like Gleam[0] would be up your alley :) As an F# guy
| myself, I am hoping it pans out, as I miss the BEAM platform!
|
| [0] https://gleam.run/
| plainOldText wrote:
| Yeah, I've known about Gleam, but I don't recall exactly why
| I wasn't too compelled to use it. I installed it with brew a
| while back, I tried a few basic examples and since then it's
| just been sitting there. I guess I should revisit. But thanks
| for the reminder anyway.
| AlchemistCamp wrote:
| > Although at first, some unfamiliar design decisions annoyed
| me, for they were not well explained in the tutorials I was
| learning the language from - e.g `arg: value` as a shortcut for
| `[{:arg, value}]` in function arguments and other places
|
| This complaint and a similar one for maps were the primary
| driver in me making an "Elixir tips" playlist of YT videos:
| https://www.youtube.com/watch?v=7w98voHko20&list=PLFhQVxlaKQ...
|
| What kinds of things have you been coding or reading in your
| Rust learning so far? I'm a pretty big fan of Herbert
| Wolverson's Pragprog Rust book and open source Roguelike
| project, as well as Tim McNamara's _Rust in Action_ (which I
| 've only gone through part of due to how each project leaves
| you wanting to keep building it after the book moves on to
| another).
| plainOldText wrote:
| I wish I had this when I learned the language. :) I'll take a
| look, as your playlist is quite comprehensive it appears.
| Thanks for sharing!
|
| Re: Rust - I've been trying out basic examples, simple web
| servers, etc; nothing too fancy. But it just seems too
| ceremonious to get even the most basic things done. I own the
| book "Rust in Action", I just didn't have the proper time to
| go over it.
| AlchemistCamp wrote:
| It takes you through the heavy lifting of writing a CHIP-8
| emulator, a database and a whole bunch of things. It really
| feels like it could have been several books and he just had
| to cut back the scope of each part to fit everything in and
| ship it.
|
| The great thing about that is that it leaves you with
| projects just begging for you to dot the "i"s and cross the
| "t"s.
| submeta wrote:
| I love functional programming because it feels natural to me to
| have functions that always return a value (method chaining or
| postfix notation FTW!) do not mutate data (and therefore avoid
| side effects), and use clear naming conventions for any
| potentially destructive functions. However, Python's popularity,
| vast library, and strong community make it a more practical
| choice for solving problems - at least when programming is not my
| primary focus but rather a means to an end.
|
| While I find Clojure, Elixir, and F# attractive, it doesn't make
| sense to use them for anything more than experimenting or playing
| around, given the resources available in Python.
| pg_1234 wrote:
| As a Python programmer, I truly believe Elixir/Phoenix is the
| best stack out there from a technical perspective.
|
| However the incredible breadth of libs and resources ... and
| most importantly the mind share (both available devs, but more
| importantly available jobs for seniors who commit to Elixir)
| means that it is still just not a competitive choice.
|
| Almost all commercial software dev is not about technical
| excellence, but rather about applying the available tech to a
| particular business domain. And there Python (and .Net, Java,
| PHP, Ruby ... even Go) are so far ahead that sadly Elixir
| doesn't look like it will make it.
| submeta wrote:
| > Almost all commercial software dev is not about technical
| excellence, but rather about applying the available tech to a
| particular business domain
|
| A manager focused on results will not make decisions based on
| beauty or excellence, unfortunately, but based on other
| criteria: What gets the job done, availability of resources,
| price. That's why PHP is still the most used programming
| language in web dev in Germany (instead of Ruby/Rails or
| Python/Django), and Excel is the most used tool for data
| analysis in the business world (instead of Python + Pandas).
| josevalim wrote:
| I guess it really depends on your definition of "make it". :)
|
| Elixir today is used by startups, unicorns, fortune 500, and
| at least two of the FAANG (for whatever it is worth). It is
| used for web apps, embedded, distributed systems, data
| processing, and making inroads on AI and machine learning. It
| has a vibrant community with events around the world, several
| dozens books, and more.
|
| It is on the [top quadrant of Redmonk][0] and [top 25 on most
| GitHub language stats][1] while being the second youngest
| language there (only older than Swift which was created by
| Apple).
|
| Considering it is a language standing on the shoulder of
| giants but started by a 30-person company, I would say we
| definitely made it (I am obviously biased!). Of course there
| is _a lot_ to improve, realistically speaking it is unlikely
| we will cross top 10 (maybe that's your definition of "make
| it") but I also want to be clear that we will be here for
| quite a while! 0:
| https://redmonk.com/sogrady/2022/10/20/language-
| rankings-6-22/ 1:
| https://madnight.github.io/githut/#/pull_requests/2022/4
| pg_1234 wrote:
| I could be wrong and I really hope I am ... I really think
| it's the best stack out there, at least until you need the
| sort of extreme performance that dictates Rust (and even
| there Rustler looks good ... particularly as Rust
| extensions shouldn't jeopardise the extreme stability of
| the BEAM).
|
| But right now it looks on course to go the way of Clojure
| or Scala ... hanging in there for sure, but never becoming
| a major player. This inevitably affects the range of 3rd
| party APIs and libs, meaning many companies will consider
| it too risky. It's not about what will impress an engineer
| (Elixir does that) it's now about what will reassure an
| accountant.
|
| I also notice that in the majority of job postings
| mentioning Elixir (i.e. just at the keyword search level)
| it is not actually the core language for the job, but
| rather a filter/attractor to try and hook top Ruby devs
| (who seem to be in short supply).
| josevalim wrote:
| Why does it have to be a "major player"? :) Going the way
| of Scala, Clojure, etc is fine. If you have a community
| where people are innovating and/or enjoying the journey,
| companies feel productive but invest and understand the
| pros and cons of the ecosystem, then to me it is all
| good.
|
| They estimate there are more than 20 million developers
| worldwide and, if a technology can reach 1% of that, I
| personally find that amazing (in the "super made it" kind
| of way).
|
| I am not saying this in a self-congratulatory way
| (especially cause we haven't reached it) but just
| generally. Anyone who worked on any sort of moderately
| used open source project has likely have gone through
| several rounds of "who is using it? anyone big?" and I
| wish people can appreciate the small victories rather
| than aiming to the highest of goals, which most projects
| will realistically (and understandably) not reach.
|
| If you or your company needs to reassure the accountant,
| then those languages are not for you, and there is
| nothing wrong with that. Other than that, your
| perspective of companies hiring for Elixir is drastically
| different than mine. :)
| mikedelago wrote:
| I don't think it's nonsensical to use less popular/exotic
| languages. I prefer to write code in languages that I like to
| write in, as long as it's a good enough tool for the job.
|
| The real problem with them is that while you and I might be
| interested in functional languages, our coworkers/managers
| aren't and we have to stick with the languages we might not
| find as immediately exciting, like python.
|
| Side node, python has Hy (https://hylang.org), which is
| essentially a lisp implementation that compiles to Python's
| AST. The entire python ecosystem and stdlib is available to Hy,
| so it's as batteries included as python is. It's a blast to
| use, but similarly I wouldn't expect my job to be excited about
| it.
| dgan wrote:
| I was randomly watching youtube videos about Elixir ("The Soul of
| Erlang and Elixir " by Sasa Juric), and I have never really been
| interested in it... I was completely wrong. BEAM/Erlang is
| amazing piece of technology, and Elixir does excellent job to
| bring in new people in.
|
| If you do web development, then just for the sake of professional
| curiosity, I urge you to go watch a couple of videos to make
| yourself in idea. I have found that some (many) features which I
| would go learn and use another tool for, are already included
| into Elixir ... Now I feel sad for doing Django for my daywork
| Existenceblinks wrote:
| 5+ years elixir exp here, about to take python/django job. Why
| do you feel sad! I just gave up finding elixir jobs for a
| couple months.
| KyeRussell wrote:
| I work for an org that does a lot of Elixir (on other teams
| though, I'm actually a Django developer!). I've heard from
| those team leads that they've had trouble hiring people with
| FP / Elixir experience, which is not that surprising to me.
| Guess it's a matter of right place right time.
| Existenceblinks wrote:
| Yeah, right place, right time, knowing right people. I
| think it's close to impossible to go through from front
| door cold.
| bullfightonmars wrote:
| More orgs should hire experienced engineers and train them
| on the job.
| UlisesAC4 wrote:
| This, a company to find skilled workers in a niche
| technology is expecting too much.
| Existenceblinks wrote:
| Practically insignificant numbers of company will do it.
| They are racing to bottom to shirk their own future
| developer pool.
| jmrobles wrote:
| No typing, no party.
|
| ...but I will include it under almost-low-code section
| Xzya wrote:
| I have been working on a library for Django that allows you to
| build reusable template components, and it is heavily inspired by
| Phoenix's Components. I just released it today, so if you are a
| Django user and find the way that Phoenix Components work
| interesting, give it a try!
|
| https://github.com/Xzya/django-web-components
| spapas82 wrote:
| This project is very similar to django components
| https://pypi.org/project/django-components/
| marhee wrote:
| > The pipe operator, |>, passes the output of a function to the
| first argument of the next function. So, instead of writing
| something like:
|
| foo(bar(baz(new_function(other_function(my_input)))))
|
| You have the option to write:
|
| my_input |> other_function() |> new_function() |> baz() |> bar()
| |> foo()
|
| The readability benefit is clear - you don't have to read the
| code "backwards" to understand what it really does.
|
| --- ( _end of snippet_ )
|
| This is a nice example of fixing a problem that does not need be
| there at all.
|
| Just use intermediate variables instead of doing clever stuff.
| Benefits:
|
| - 1 way of doing stuff
|
| - variable names will help readers understand the intention of
| the function calls
|
| - you can do explicit error handling for each call
|
| Note: in contrast, in shell prompts the pipe operator is useful
| because:
|
| - less typing counts here
|
| - prompts are use-once mostly, maybe repeated (history &
| scripts), but readability is not a mayor concern
|
| - commands deal with large amount of data often, hence storing in
| intermediate variables can be expensive or even impossible.
|
| None of these points are valid for a programming language.
| (Unless of course you just fancy the syntax)
|
| Btw I find the joke about "bearded wizards" not very inclusive
| towards women. It feels assuming that only men (can) be that
| wizardry.
| h0l0cube wrote:
| No downvotes from me btw, but I think the author and just about
| most people using Elixir (which tends to not be a first
| language for most in the community) have used the classic-style
| of temporary variables for lack of any other option. Certainly
| in my own experience the pipe operator has eliminated those
| redundant expressions rendering the code more concise,
| expressive, and hence more readable. Many APIs in other
| languages emulate something similar with method chaining for
| this very reason (see Fluent APIs).
|
| Extracting variables out of if-expressions can still be useful
| for improving readability of long boolean expressions though.
| [deleted]
| josevalim wrote:
| I would find such principled approach to be unproductive. The
| same could be said about Python, the `.` is equally syntax
| sugar for passing the object as first argument. So if we take
| this Pandas code: df.sort_values('dep_date')
| .groupby('name')['duration'] .transform('cumsum')
|
| If we were to pass df as first argument in nested calls, I
| would find it less readable. But I would also find using
| variables in this case to be more noise than helpful:
| sorted_df = df.sort_values('dep_date')
| grouped_duration_df = sorted_df.groupby('name')['duration']
| grouped_duration_df.transform('cumsum')
|
| The variables are just repeating some of the information found
| on the right side and IMO they end up getting in the way of
| understanding the whole pipeline.
| marhee wrote:
| You could reuse df (as the method presumably change df), in
| addition:
|
| - you have more room to comment what the intention of the
| code/call is
|
| - you have room to handle / check for errors
|
| For example, the "sort_values" and "groupby" in you example
| are obvious most readers. But "transform("cumsum") is
| probably obvious to you but I don't know the intention of the
| code.
|
| By reassigning to df it makes it clear that the returned
| value from each of the functions is a `df` (some kind of
| query builder I think). Actually rewriting you r code I
| discovered your groupby did a groupby and then selected a
| result column I think.
|
| So we would get: // sort result on
| dependency date df = df.sort_values('dep_date')
| // ... check if sort_values worked (i.e `dep_date` is valid
| column) // group result by name and select
| duration column durations =
| df.groupby('name')['duration'] // compute columns
| cumulative sum of durations sum =
| durations.transform('cumsum')
|
| I agree its much more verbose, so this won't work if you
| (just) want conciseness.
| josevalim wrote:
| If you reuse the variable, then you are not getting any of
| the alleged benefits of using variables. The same name
| tells little except it is perhaps the same data type and in
| Elixir you would also get this information from the module
| you are invoking: text |>
| String.split(",") |> Enum.join(" ")
|
| You could also equally add comments between the lines in
| the dot example:
| df.sort_values("dep_date") # group and select
| .groupby(...)[...]
|
| Although most of the comments above are discardable (IMO)
| because they are restating the code.
|
| My point is: sometimes I will break out into variables to
| get some of the benefits you mention. But forcing all
| intermediate steps to assign to variables is as harmful as
| using "|>" or "." exclusively and forgetting about
| variables altogether. If you need to add error handling,
| code comments, etc, you can break out of the pipeline as
| needed.
| h0l0cube wrote:
| > won't work if you (just) want conciseness
|
| I think Jose's example provides the best of both worlds,
| conciseness and readability.
|
| > you have more room to comment what the intention of the
| code/call is
|
| There's nothing stopping each pipe expression from having a
| comment of its own if you lean towards literate
| programming, or you feel that the pipe function + arguments
| begs further explanation to unfamiliar developers.
|
| > you have room to handle / check for errors
|
| You can pipe your results into a validation function. Ecto,
| the go-to database mapper, has exactly this pattern.
| Failing fast is idiomatic Erlang/Elixir (rather than let
| the process live on with corrupt state) which means if the
| validation fails, it ought to raise an exception so the
| external caller can fix their call/request, or if it's a
| bug, the developer can be alerted to fix the code.
| freedomben wrote:
| > _You could reuse df (as the method presumably change
| df),_
|
| Then what's the point in assigning to intermittent
| variables (as your criticism about the pipe was)? You don't
| get any added clarity about the intermittent intentions
| that way...
| UlisesAC4 wrote:
| If you need temporal variables to give context you have other
| problems with the naming of the function that you are calling
| in the first place.
|
| We have used temporal names between function calls not because
| it was more readable but because chain of methods was not an
| option as you have said.
| shaundon wrote:
| I've been using Elixir with Phoenix and Liveview at my job for
| the past three months as part of a small team building a non-
| trivial web app (https://duffel.com/links). I'm mostly a front-
| end developer and was brought in to handle the UX side. Prior to
| this project I've spent the last 5+ years in the React world.
|
| I found a lot of what the author says to be true. I'm used to the
| nightmare that is managing front-end dependencies, and it was
| refreshing to use something so 'batteries included' that comes
| with most of what I need.
|
| It took me a while to get my head around the Phoenix + Liveview
| way of doing things, but when my mental model clicked into place
| and I stopped trying to do things the React way I became a lot
| more productive. When I had an autocomplete updating live as the
| user typed all going over the websocket without me writing any
| JS, it felt magical.
|
| However I definitely found a lot of sharp edges that the author
| doesn't mention. We struggled a lot with any non-trivial UX, for
| example with the autosuggest mentioned above I had to add a lot
| of JS to handle things like being able to use the keyboard's
| arrow keys to select options. Whenever I jumped into the JS world
| it often felt like I was fighting against Phoenix, and had to
| resort to using 'phx-ignore' a lot. It was frustrating to
| continually struggle to do things I knew how to do easily in a
| pure JS environment.
|
| Another area I struggled a lot is Elixir's syntax. To me, it
| feels like there are too many operators. The author touches upon
| it towards the end when they mention things like '\\\' for
| default arguments, '<>' for joining strings and '++' for joining
| lists. It's a lot to wrap your head around at times.
|
| Some of the fault for this lies with me; we were working to a
| tight deadline so I didn't have time to dedicate to learning
| Elixir, Phoenix and Liveview from first principles, I just jumped
| in out of necessity. Had I spent more time on the foundations
| first I may have been able to avoid some of these pitfalls, but I
| do think it illustrates that like many 'do everything'
| frameworks, there's a steep learning curve to doing non-trivial
| things. It's a powerful tool and I'm optimistic about its future,
| but I'm undecided if I'd choose it for a future project that has
| significant front-end requirements at this stage.
| POiNTx wrote:
| > Whenever I jumped into the JS world it often felt like I was
| fighting against Phoenix
|
| I've had the same experience and this is something I've tried
| to tackle recently. I've started working on LiveSvelte which
| allows you to plug in Svelte components directly into your
| LiveView, while still being able to push events to the server
| with a `pushEvent` function on the client. I've only started
| working on it this week but I think it's a promising idea. It's
| not React though but you could develop a similar package with
| React, I just much prefer Svelte :)
|
| https://github.com/woutdp/live_svelte
| IceDane wrote:
| Which part of this app is using LiveView? Since what you link
| to is using next.js. Are you guys mixing the two?
|
| I really want to find a reason to build something with elixir,
| and it might be viable for my current work project. We won't be
| replacing our next.js frontend, though, that's for sure, though
| I wouldn't mind experimenting with it.
|
| I'm mostly interested in deploying elixir on the backend, since
| we are using microservices, and there would definitely be a
| couple of services where elixir seems like a great fit. OTOH,
| we are also pushing some data through ML models, and it seems
| like Python is still the only real choice for this kind of
| stuff. I really wish it weren't the case, since the python
| interpreter with its GIL is just a piece of crap, to be frank.
| shaundon wrote:
| Ah sorry, I should have clarified in my original message. The
| page I linked to is our public marketing site, which is a
| static site built with Next. The Phoenix application is the
| product that the site is talking about (Duffel Links).
| AlchemistCamp wrote:
| It sounds like you were able to be reasonably productive
| without even any time to learn the framework, so I'd say you
| did alright!
|
| I'd say up until the recent focus on LiveView, Phoenix has been
| very easy for devs with experience with Rails or Rails clones
| in other languages to learn. Recently, with all the LiveView
| changes and the new components, it's been harder, but I think
| it's finally stabilizing a bit and I've got to say the newly-
| released Phoenix 1.7 is another significant step forward in
| terms of productivity for new apps.
| rTX5CMRXIfFG wrote:
| Serious question--if you were on a tight deadline, why did you
| choose a tech stack that you still had to learn? Leveraging
| existing knowledge is exactly what anyone in a rush should be
| doing.
| shaundon wrote:
| I wasn't personally involved in making this decision, I was
| brought onto the project after it was taken, but there was a
| perception that we'd be faster if we did everything as a
| full-stack application. In fairness, we did deliver what we
| set out to do so it was a success, even if there were some
| rough edges to deal with.
|
| Also bear in mind that I'm only covering my front-end
| perspective on this. I think the back-end developers involved
| on the project found it much easier to work with as they were
| already experienced with Elixir and Phoenix. For them, a
| tightly-coupled front and back end meant that they could
| change the way things worked and it was straightforward to
| update a few functions in Elixir and then the HEEX template,
| as opposed to a decoupled setup where we'd probably have been
| communicating using a JSON API and changes would have had
| more of a barrier to adopt.
| linesinthesand wrote:
| Could someone please write this same article but for GoLang
| michaelteter wrote:
| No offense to TFA author, but I don't think this is doing to sell
| Elixir to Python people. In fact, I have serious doubts as to
| whether most Python lovers would be willing to set aside their
| beliefs and practices to learn the Elixir way.
|
| Perhaps Phoenix and LiveView will be the gateway drug, but even
| to reach that point requires a lot of effort to understand
| functional programming and Elixir.
|
| Python has some functional capabilities, but in my experiences
| with Python devs, those are little used and even shunned.
| Imperative, mutating loops are the Python way; and to suggest
| otherwise is to hear "But why would I need that? This (long
| functions with mutations everywhere and loops) is fine."
|
| I went from Ruby to Elixir, and even with my basic Clojure
| experience, it was an effort. It was worth it, but I think the
| apparently similarity of Elixir to Ruby is actually a negative.
| They look awefully similar, but their use is vastly different.
|
| As for Django vs Phoenix, I would argue that Phoenix has a much
| cleaner story for doing everything that Django can do and more.
| People promote Django for the "batteries included" aspect, which
| mostly just means "I get free user/auth system and built-in
| scaffolding for my CRUD." But those are things which are very
| easy to add to Phoenix (and Rails, which Phoenix is roughly
| similar to). Yet people choose Django for these little freebies
| which almost always get thrown away or ignored in real production
| worlds. For a quick proof-of-concept, it's nice. But for real
| projects it doesn't add value enough to offset the crufty
| boilerplate OO-centric code that results.
| spapas82 wrote:
| I've got experience in both Phoenix and Django and I disagree.
| In my view, Phoenix is the _less_ clean one: Django does not
| generate anything through scaffolding like Phoenix. Your CRUD
| (and auth and forms and everything more or less) is generated
| by overring the built-in Django classes or the classes offered
| by the packages. Nothing gets thrown away in real production;
| you use your class hierarchy to change it to your requirements.
| I know that inheritance and polymorphism seems like a 90 's
| technology but this actually is a solved problem in web
| frameworks and _does_ work excellent.
|
| On the other hand, I agree with you that everything that
| Phoenix generates through its phx.gen generators are for demo
| purposes and will get thrown away eventually. This, along with
| the fact that everything is a function results in having to re-
| invent the wheel multiple times in your project without any
| saferails on how to actually architecture it. Should I use a
| context? What to put there? What's the point of views? Oh views
| are removed now? So, unless you are really very careful or have
| much experience/guidance this will result to a total mess.
|
| The batteries included aspect of Django means that if you are a
| novice developer and follow the best practices you'll get a
| fine project without too much effort. It isn't really about the
| batteries, it's about the fact that you'll know how to
| implement each thing you need in a web project. I can confirm
| to that that because we've got 12-year old production running
| Django projects which were developed by a totally novice Django
| developer (me).
|
| Try to do that in Phoenix (still being a novice developer).
|
| Now I don't want to abolish Phoenix. It's a fine framework
| considering its age and its popularity and number of people
| contributing to. However you must be very careful before
| considering to use it for a real project that will be used and
| supported for the years to come, expecially if your alternative
| is something as proved as Django. Personally, I use Phoenix
| only on projects where its real-time capabilities will be the
| protagonist.
| bboygravity wrote:
| > I use Phoenix only on projects where its real-time
| capabilities will be the protagonist.
|
| As a web user (not dev) I would say real-time (as in super
| fast?) should always be the protagonist?
|
| To me that's the most important factor that makes the
| difference between nice and shtty website.
| spapas82 wrote:
| Not really. Real time is not the same as super-fast. You
| can be real time but super slow or super fast using
| traditional request/response web apps.
|
| When I mentioned real-time I was talking about apps that
| need to use web sockets to have fast client-server
| communication. There aren't many apps where this is
| required (or worth it).
| traverseda wrote:
| Real time like a chat app, or a video game or something.
| Not just a fast site. Seems like most "real-time" sites are
| slower as they have a harder time taking advantage of
| caching and the like, or use a lot of slow client-side
| javascript that inevitably works poorly.
|
| Basically if you need the server to be able to change the
| data a user is currently looking at, collaborative multi-
| user stuff mostly. Liveview could be great if you're
| building google docs, but you could probably build youtube
| using just a more traditional framework like django.
| mixmastamyk wrote:
| Been looking at CRDTs lately for this, sounds like Elixir
| would be a good fit. Although what I've seen before has
| used C++ or Rust? to compile to wasm for the graphics
| part of the front end. Do all these technologies work
| together well?
| AlchemistCamp wrote:
| > "On the other hand, I agree with you that everything that
| Phoenix generates through its phx.gen generators are for demo
| purposes and will get thrown away eventually."
|
| The parent didn't say that and it's not true in my experience
| writing Phoenix apps over the past six years. I usually add
| to the generated contexts, controllers or now live views, but
| I often leave the migrations as is. Even when making a
| migration to edit an existing schema, I still use the Ecto
| generators. The _only_ thing I've often thrown away large
| parts of was the template.
|
| I've taken over about as bad of a Phoenix app as you can
| imagine (made by a rotating cast of outsourced contractors
| over years, no use of Ecto relations, no use of "resources"
| (just get and post), not using built-in validations, pinned
| to a version of LiveView from two months after its initial
| release... and using jQuery to drive it). Due to Elixir's
| immutable, functional nature, rehabilitating the code base
| has actually been a bit easier than some Django apps I've
| seen. The most painful part has been unraveling the jQuery.
|
| IMO, Django still hasn't caught up with 2014 Rails.
| freedomben wrote:
| My experience as well. The generated code is absolutely
| kept and used (excepting the template, but even that serves
| as a nice example to follow for people who are newer).
| Mainly the only changes are to add validation code and some
| business logic here or there depending on how complex the
| behavior needs to be (again mainly validation). The
| generated code is a big help, and we still use it for every
| new model despite being able to easily add new stuff
| manually.
| josevalim wrote:
| > Django does not generate anything through scaffolding like
| Phoenix
|
| I was one of the co-authors of Devise, which is an integrated
| authentication solution for Rails (similar in spirit to
| Django), and you will easily find people who swear that the
| code generation solutions are miles better. That's because
| eventually they'd want to customize how the framework or
| library work and then, instead of simply being able to change
| the code, you need to find the exact hook or configuration to
| get the behavior you want. Eventually, you end up with
| hodgepodge of changes that you can only understand when
| looking at the framework and your code side-by-side.
|
| Perhaps this is one of the topics where there is no
| "superior" answer, besides personal preferences and past
| experiences. I totally understand why someone would prefer
| Django or Devise, but our premise is that eventually you will
| want to customize it, therefore giving you control upfront is
| the better way to go about it. However, I would say it is
| incorrect to say they are for demo purposes in both Phoenix
| and Django cases, as there is plenty of evidence otherwise.
|
| It is also a matter of framework philosophy. Phoenix aims to
| give all the necessary foundation for building applications,
| and then not get in your way, rather than owning all aspects
| of your application lifecycle. I believe frameworks like Ash
| (which also runs on Phoenix) take the latter approach.
|
| > Oh views are removed now?
|
| To clarify, Views are not removed. Phoenix is still MVC. The
| difference is that the templates in your view are defined via
| `use Phoenix.Template`, rather than `use Phoenix.View`. You
| can migrate (or not) at your convenience.
| spapas82 wrote:
| > instead of simply being able to change the code, you need
| to find the exact hook or configuration to get the behavior
| you want.
|
| I don't think that this is a bad thing. This is the purpose
| of a framework. To extend its functionality. If I wanted to
| re-write everything (or change the generated scaffolds)
| then I'd skip the framework and use libraries directly.
|
| I'd like to point out the biggest problem with scaffolding:
| Let's suppose I use scaffolding to generate a scema /
| database table in phoenix, along with all the bells and
| whistles. I'm happy; instant code. I customize all the
| scaffolds as I like (i.e change html layouts, fix the
| schema/migration for fks, fix the queries, improve forms
| etc). I'm happy; everything works as I like. After 1 hour I
| notice understand that my table is missing a field. I'm
| sad. Now I've got two equally sad options:
|
| * Delete _everything_ that phoenix has generated for me,
| drop the schema, re-generate the scaffold (with the new
| field) and re-apply all my customizations _or_ * Add the
| field myself by adding a migration, adding it to the
| schema, fixing the tests, adding it to changesets, fixing
| the templates, fixing the queries and praying I haven 't
| forgotten anything.
|
| Now I'm very sad.
|
| What would happen in that case (forgot a field in the
| database) in Django? Add the field to the model and re-run
| the migrations. That's it. Happy days!
|
| > You can migrate (or not) at your convenience
|
| Yes, I know that the views are still there but my
| understading is that they won't be generated anymore (so
| the steer is to not use them anymore, at least for new
| code). However, my main argument was that Django is better
| at holding your hand to produce acceptable code even if you
| are not experienced with the framework nor you have
| mentoring. The fact that now you have even _more_ options
| (i.e you can use views if you want and think you need them)
| strengthens that argument.
| josevalim wrote:
| If you need to change it, you would add it to the
| migration, schema, and then in the necessary templates.
| Some fields are private, read-only, etc. so you would
| change your templates accordingly. Some fields you want
| to change via a button press, others via a form, and so
| on. The whole point is that you can evolve the generated
| structure based on your needs.
|
| > (i.e you can use views if you want and think you need
| them)
|
| I was mostly speaking about existing applications. New
| applications have a clear path forward.
|
| I don't think this strengthens your argument the way you
| think. I _bet_ Django also has features that were used in
| the past and are no longer favored now, but still
| supported for backwards compatibility. This is in no way
| a phenomenon exclusive to Phoenix.
| dasil003 wrote:
| If your argument is that a configurable framework is
| easier than code gen for beginners, I agree. But that
| said, you don't seem to be acknowledging the fundamental
| tradeoff which cuts both ways. Ultimately it depends on
| how close you want to stay to the paved path. I've built
| enough web products at this point that I'd rather have
| auth primitives than a configurable framework as the
| latter will be way more complicated than necessary to
| meet my needs.
|
| For me it comes down to keeping business logic out of my
| framework. The logical extension of the framework + hooks
| model can be seen in something like Drupal. You can get
| amazing volumes of functionality launched quickly, but
| the UX is ERP-like in its rigidity. Obviously Django is
| not like this in the large, and the auth/admin stuff are
| much higher power-to-weight ratio than anything in
| Drupal, but it's an interesting case study in looking at
| the implications of drawing different logical boundaries
| between framework and application.
| fdeage wrote:
| With Phoenix 1.7 being released, will there be a new
| edition of "Programming Phoenix"? The latest one covers
| Phoenix 1.4, which is already slightly outdated. I think
| having an up-to-date book would be of great value for
| Phoenix beginners :)
| scwoodal wrote:
| I don't think 1.7 is officially out yet as it's sitting
| at rc-3.
| fdeage wrote:
| It's been released yesterday :)
| https://phoenixframework.org/blog/phoenix-1.7-final-
| released
| conradfr wrote:
| Nice.
|
| It didn't seem to have really made the frontpage of HN
| despite a lot of votes.
| AlchemistCamp wrote:
| The same publisher has a "Programming Phoenix LiveView"
| book, which is probably your best bet at this point.
| AlchemistCamp wrote:
| Is there a channel where we can share suggestions for the
| upgrade guide?
|
| I think it would save people some time if the phx 1.6 ->
| phx 1.7 upgrade instructions started with the following two
| steps:
|
| 1.) Upgrade LiveView to 0.18.x (with link to https://hexdoc
| s.pm/phoenix_live_view/changelog.html#0-18-0-2...)
|
| 2.) Update web.ex macros for Phoenix Component (with link
| to
| https://hexdocs.pm/phoenix_view/Phoenix.View.html#module-
| rep...)
|
| Then the upgrade doc will work and people won't get stuck
| trying to follow those instructions with a Phoenix 1.6 app
| using whatever version of LiveView they had before.
| josevalim wrote:
| Please open up an issue.
| AlchemistCamp wrote:
| Okay! Will do.
| nickjj wrote:
| I updated my example Docker / Phoenix app from 1.6 to 1.7
| this morning.
|
| I put it all into 1 commit:
| https://github.com/nickjj/docker-phoenix-
| example/commit/3733...
|
| There were a number of things not covered in the upgrade
| guide. Lots of small changes between what the new app
| generator provides, csrf tokens being set in a different
| way, etc..
| noloblo wrote:
| Elixir haskell and erlangs concurrency and parallelism story
| far outweigh any imperative pythonic benefits or idioms IMHO
| college_physics wrote:
| > I use Phoenix only on projects where its real-time
| capabilities will be the protagonist
|
| Yep, that feels sound advice (and motivation). I would add
| more broadly "federation capability" (in the style of the
| fediverse / activitypub but also wherever that
| decentralization path might take us in the near future) as an
| important dimension to look into. Remains to be seen if the
| "telecoms/erlang" pedigree of elixir is a critical element in
| this respect. There are already some important projects based
| on elixir [0] [1] but also some django based efforts [2] [3].
|
| [0] https://bonfirenetworks.org/docs/architecture/
|
| [1] https://docs.joinmobilizon.org/administration/install/sou
| rce...
|
| [2] https://docs.funkwhale.audio/stable/installation/
|
| [3] https://docs.jointakahe.org/en/latest/installation/
| freedomben wrote:
| It is only sound advice if you already know Python/Django
| really well and don't mind context-switching your language.
| If you know Elixir/Phoenix well, you can easily crank out
| simple sites that don't use any real-time stuff as well as
| any other framework, and you get the added benefit of
| blazing fast (pre-compiled) templates and a highly robust
| database connection pool. Personally I prefer to keep as
| much as possible in the same language/ecosystem rather than
| having to straddle.
| college_physics wrote:
| sticking within a single capable ecosystem is optimal
| here-and-now but your mileage might vary as we go
| forward. its always hard to forecast but even if you
| discount alot of the ML/AI hype, its quite likely that
| 2-3 years from now expectations will be for much
| "smarter" services.
|
| whether delivering such upgrade can be achieved with
| microservices and API's or whether a platform can deliver
| functioning "monoliths" that compete also in such a new
| landscape is not clear (not to me anyway)
| andy_ppp wrote:
| I've personally found Elixir to be a nice balance compared to
| something like Haskell or even Rust in terms of FP. Most
| things, certainly testing are made simpler by immutability and
| the actor model makes parallelism much simpler to reason about.
| I've no doubt python is a great language for some things but
| once Elixir figure out the best way to add types I'll be
| extremely happy that the language does everything I want.
| Especially with ChatGPT now you can ask it about topics in
| language learning that you don't understand and it gives really
| great examples to help, so for me learning idiomatic ways of
| programming in Elixir or another language got a lot easier.
| college_physics wrote:
| There is this joke that you don't need to outrun a python, you
| only need to outrun the humans it is chasing.
|
| Elixir does not need to outshine Python it only needs to
| position better than other "functional style" languages on
| offer as the "go-to" language if one wants to add such a
| capability in their programming toolkit.
|
| In practice this means outshining Clojure. And on this front
| Elixir definitely does a good job: E.g., there is no such thing
| as Phoenix in Clojure. People seem to advance some arguments
| along the lines: "you don't really need frameworks, just
| compose your own" but this is not cutting it for the masses :-)
|
| In a universe where there are millions of different ways of
| doing things having a well thought, opinionated, proposal is
| actually an advantage. The limitations (if any) show much later
| in the cycle when the choice of programming language might even
| be the least of your worries.
| dgb23 wrote:
| I don't think these languages really compete outside of a
| fairly narrow dimension. They both seem to be doing well. But
| that's beside the point.
|
| People in the Clojure community have been trying to build
| such frameworks. But every one of them seems to stay in a
| weird niche where they're not comprehensive and _easy_ enough
| to draw in people who'd use something like Django et al.
|
| I think one of the reasons is that they're all trying to
| cater to the crowd that wouldn't use such a framework anyway.
|
| Secondly it's already very quick to create a web app in
| Clojure. If you use a set of libraries you pay with some
| initial setup/thinking/choosing cost. The benefit is then to
| have a program that is more malleable and composable, which
| is kind of the point for many who choose Clojure in tge first
| place.
|
| There's really a mismatch of expectations and philosophy I
| feel.
| college_physics wrote:
| The "visibility" of frameworks and the onboarding "ease"
| are important features for many reasons but there are more
| attributes that shape people's choices. Talking primarily
| about open source ecosystems, being able to economise on
| resources is a major advantage. A "hello world" web app or
| a "neural net without dependencies" might be quick to do in
| any modern language but one major pathway to add value is
| when non-trivial domains are represented in usable detail.
| This is where a community culture that promotes pooling
| resources behind a few core libraries or frameworks plays
| an important role. It enables building on top a second
| layer of abstractions, plugins, interoperable API's et.
| Django is one example but the Python world has also "one
| stack" for numerical calculations (numpy, pandas and
| friends) and that was maybe more instrumental for adoption.
| noloblo wrote:
| I think this article does capture the magic of elixir phoenix
| live view that is impossible in the async await madness hell in
| python. I cannot wait to try elixir Phoenix live view, elixir
| |> pipes, :atom pattern matching and ets pids to send and
| manage processes across servers none of these AFAIK are
| currently possible with the GIL and single threaded nature of
| python
|
| As the venerable prof Joe armstrong would say
|
| you need erlang and haskell for fp you need c for high
| performance you don't really need cpp Java python c# etc
|
| Also as an aside does anything in haskell have something
| similar in spirit to phoenix or live view?
| ch4s3 wrote:
| You can pattern match on basically any shape, not just atoms.
| Imagine you're parsing a protocol over tcp and want to grab
| groups of characters between deliverers, you can pattern
| match that. I rewrote an hl7 parser from Java to Ruby to
| Elixr some years ago and the elixir implementation performed
| as well as Java and was more readable by miles.
| bongobingo1 wrote:
| > You can pattern match on basically any shape, not just
| atoms. Imagine you're parsing a protocol over tcp and want
| to grab groups of characters between deliverers, you can
| pattern match that.
|
| Ex: https://youtu.be/MaQqa21uxQ8?t=548 (note that "binary"
| here is a "binary blob of bytes").
|
| Andreas pattern matches on the magic byte, then encoded
| string length, then the string (using the previous matched
| length), then an int, all in the function header, no if-
| else-try-catch mess.
| KyeRussell wrote:
| It seems like the basis for your comment is weird stack
| tribalism that you've very evidently bought into, rather than
| anything actually...worth discussing.
|
| It then comes as no surprise that throughout your entire
| comment you didn't seem willing you yield any ground to Python
| or Django at all.
|
| It then comes as no surprise that your assertions about Django
| are counter to my experience, as someone that by the sound of
| things has worked with Django a lot more than you have.
|
| I have only worked on one production Django project that
| *didn't^ use Django's auth system. And the fact that you call
| Django's generic class-based views "scaffolding" - a term that
| I seldom hear in Django spaces but hear all the time in Rails
| spaces - further speaks to your lack of familiarly. Most
| production Django projects I've worked on have made extensive
| use of either these generic class-based views or the Django
| REST Framework analogues, which - whilst not part of core
| Django - still speak to the usefulness of the pattern.
|
| It honestly sounds like your experience with Django - if any -
| has been treating it like Rails. Which - honestly - is mostly
| fine. In my eyes, the frameworks are comparable in...most ways.
| But your assertion that these batteries are thrown away in
| production contexts is just wrong. Unless you want to tell me
| that I've spent ~a decade earning a living working with Django
| and somehow not managed to do any "real" work, perhaps consider
| the global applicability of your personal experience.
|
| It's really disappointing to see the re-uprising of Ruby (and
| Elixir) developers positioning themselves as the enlightened
| elite against the hoards of plebeian Python developers. I
| without a doubt include your comment in this critique. I
| understand that given Elixir's increased FP focus that the
| community can't avoid FP elitism. Doing it for Ruby though?
| It's just cringey. I've got no beef with Ruby, Rails, or the
| development communities of either, except for the fact that
| people are feeling the need to pick up this ridiculous turf
| war.
|
| Given that Python is my daily driver, Python spaces are where
| I'm usually active in. Ruby is seldom mentioned. Whenever I go
| to a Python-related HN thread, I don't have to scroll far to
| see some Ruby developer making some thinly veiled assertions
| that Python developers are un enlightened idiots. If I look at
| a Ruby thread, there's always someone salty about not being
| able to get the Python drones on their team to use the One True
| Language. It feels like I've gone back in time 15 years.
| josevalim wrote:
| It is perhaps utopia but it would be nice if we could discuss
| those topics without falling into camps.
|
| For example, I could argue for hours about the benefits of
| immutability, but I still believe that imperative loops are
| clearer than functional ones. There is even a repository with
| solutions for nested traversals in different languages and
| the Python one is my preferred by some margin:
| https://github.com/josevalim/nested-map-reduce-traversal
| JPKab wrote:
| "Python has some functional capabilities, but in my experiences
| with Python devs, those are little used and even shunned.
| Imperative, mutating loops are the Python way; and to suggest
| otherwise is to hear "But why would I need that? This (long
| functions with mutations everywhere and loops) is fine.""
|
| Thank God I'm not stuck with low talent clowns like that.
|
| Writing highly functional python isn't hard anymore, especially
| making use of mypy strong types, data classes, generator
| expressions/etc.
|
| Using dict unpacking combined with things like list comps is a
| really simple way to get trad Python devs getting more
| functional. My team is a bunch of experienced Python devs who
| happen to live Haskell/Clojure/etc so I guess that makes things
| easier.
| foldr wrote:
| > Thank God I'm not stuck with low talent clowns like that
|
| Woah! Python's a multiparadigm language. Using loops and
| mutation is a perfectly fine way to write Python code. For
| sure there are some kinds of code that lend themselves to a
| functional style, but equally, there are other cases where
| mutation is the more straightforward approach.
|
| Making personal attacks on (admittedly non-specific) people
| for not being functional programming zealots is a great way
| to make a thread dumber.
| paedubucher wrote:
| > Python has some functional capabilities, but in my
| experiences with Python devs, those are little used and even
| shunned.
|
| I like to use things like filter, map, reduce or list
| comprehensions, but I see very few of those in my coworkers'
| code bases.
|
| When Python introduced pattern matching, it was rather a
| pattern-aware switch/case, which does not return a value, as
| such a construct in a functional programming would do.
|
| > I went from Ruby to Elixir, and even with my basic Clojure
| experience, it was an effort.
|
| I tried out Elixir twice so far, and since the last time, I
| worked through 300 pages of SICP. I still have to twist my mind
| when I'd like to process nested maps or the like in Elixir now.
|
| > It was worth it, but I think the apparently similarity of
| Elixir to Ruby is actually a negative.
|
| However, Ruby provides a lot of higher-order functions, such as
| group_by and the like. If you're used to functional-style Ruby
| code, the transition is easier.
| danjac wrote:
| I use Django not just for the framework, but for the larger
| Python ecosystem of packages for just about any eventuality,
| whether that be NLTK, pandas, or whatever (and if I didn't need
| the full weight of Django there's always Flask or FastAPI).
|
| That's not to knock on Elixir or Phoenix, and I like Elixir a
| lot, but there is usually more to projects I've worked on than
| CRUD apps, and I've found with languages with smaller mindshare
| and ecosystems that you can spend more time reinventing wheels
| because a particular library is missing, or it's there but is
| no longer maintained.
| winrid wrote:
| The Phoenix docs don't look like they even hold a candle to
| Django. I spent 5mins in it and still don't know how to define
| a model. I eventually figured out a doc section called "Ecto" -
| so i had to know what ecto was to find it. Then, in those docs
| I still don't know how to define models. Do they expect me to
| manage my database and schemas separately and generate the
| models from that?
|
| That's completely opposite what Django does, and that's partly
| why Django is so productive.
|
| I don't think Pheonix and Django are competitors. They are too
| different.
| arrowsmith wrote:
| Phoenix doesn't have the concept of a "model". The
| functionality of what Rails (and I guess also Django? Idk)
| calls a "model" is split between a few different places:
| schemas, changesets, queries, the repo.
|
| It felt weird at first, coming from Rails, but after getting
| used to it I don't miss "models" at all. ActiveRecord models
| in Rails are a vastly overloaded concept anyway and pretty
| much always degenerate fast into an ungodly mess as your app
| grows. I prefer Phoenix's approach.
| winrid wrote:
| Yeah, for a big complicated system, I don't think defining
| everything in models is great. I don't do that, and it's
| also not how fastcomments is built.
|
| But for simple stuff it's amazingly productive!
| Cyph0n wrote:
| I'm not really familiar with Phoenix, but skimming through
| the section linked below, it seems to cover what you're
| looking for? Basically, you use a tool to generate your model
| + migration code and then run the migrations.
|
| https://hexdocs.pm/phoenix/ecto.html#using-the-schema-and-
| mi...
|
| As for the comparison to Django, I don't really expect any
| web framework to have docs at that level. They are simply
| huge and have been around for quite a while.
| winrid wrote:
| Yes, I skimmed through that and was surprised to see it be
| compared to Django. It's different.
|
| Django is for building CRUD apps quickly. That's it. It's
| not for the long haul of super complicated apps, which many
| projects don't ever reach before they fail/get abandoned.
| bostonvaulter2 wrote:
| You might be interested in the relatively new Ash Framework
| that builds on top of Phoenix and has much more built in:
| https://ash-hq.org/
| Scubabear68 wrote:
| I haven't gotten through the whole article yet, and haven't
| encountered Elixir before, but I really like the popes ideas. I
| am going to dig into that a little more. Are there other
| languages that have similar constructs (outside of shells!)?
| sodapopcan wrote:
| Ocaml, F#, probably others.
| ak_111 wrote:
| What is the productivity advantage of Elixir/Phoenix over other
| frameworks when using it for implementing more mundane SaaS (some
| dashboards, some CRUD,...) rather than the game lobby feature
| mentioned in the post?
|
| I am a developer with significant non-web development experience
| (Although I know pure JS and Erlang quite well), who is
| interested in learning some full-stack development to implement a
| SaaS on the side and would like to zone in on the most productive
| framework possible.
| realusername wrote:
| As long as you don't have any dynamic part to your app, it's
| pretty much the same, it's the dynamic areas that are very very
| productive with live view.
|
| I've implemented a simple multiplayer card game in about a day
| for example.
| dugmartin wrote:
| For me it's not just the framework (although that is nice) but
| really the VM that it runs under (BEAM/OTP). Running an app on
| the BEAM means removing the need for external servers like
| redis/memcache for cacheing and whatever queue management
| system you pick.
|
| For a SaaS app this means instead of trying to orchestrate a
| bunch of services via some complex system (k8s, etc) you run
| everything under one VM that both scales across both local CPU
| cores and distributed nodes in the same network easily.
|
| As for dashboards and CRUD UI that is improving in the latest
| Phoenix release. I have a 5 year old Phoenix app that I wrote
| that is still running in production and I generated all of the
| backend admin and most of the frontend using Phoenix's
| generators. However that did result in a lot of nearly
| duplicate view code. With 1.7's focus on shared common UI
| components the shear volume of template code is reduced, (but
| not eliminated).
|
| If I were you I'd wait for 1.7 to fully release and then try it
| out for a couple of hours and generate some simple app to get a
| feel for it. I've been programming professionally for 30+ years
| and I've written in a lot of languages and writing Elixir code
| just feels good. Jose Valim got a lot right with Elixir (and he
| sets a great tone - just read his comments in this very comment
| section).
| clessg wrote:
| > If I were you I'd wait for 1.7 to fully release and then
| try it out for a couple of hours and generate some simple app
| to get a feel for it.
|
| Good news: Phoenix 1.7 final was released yesterday!
| https://phoenixframework.org/blog/phoenix-1.7-final-released
| (HN: https://news.ycombinator.com/item?id=34929159)
|
| Although, if I were an absolute beginner, I might still
| consider waiting a _little_ bit for the various resources to
| be updated to 1.7. That seems to be happening fast, at least.
| Or just go for the excellent Phoenix guides, which are
| already updated: https://hexdocs.pm/phoenix/overview.html
| di4na wrote:
| I would say probably on par. It is a bit less battery included
| but far far easier to adapt and far cleaner.
|
| The moment you need _anything_ remotely dynamic, then the
| advantage is imho close to a 5x at least.
| Spivak wrote:
| Assuming the author is in the comments, the paragraph about data
| immutability is wrong. Integers are immutable in Python, when you
| created the lambda the _name_ x is in its closure. When you
| assign to it it changes where the name is pointing to. Elixir
| does something wild and completely different. When you assign x
| that second time at that moment is creates a new variable behind
| the scenes and you transparently start using that one when you
| now refer to x in that scope. So lambda has a reference to x@0
| and your outer scope has a reference to x@1.
| otreblatercero wrote:
| Thanks for pointing that out, I knew it was a closure because
| of the Elixir in Action book, and the example's explanation
| threw me off balance.
| Im-Batman wrote:
| Is there an issue with the link?
| Mizza wrote:
| Was tinkering, sorry, should be fixed now. I wrote this but
| didn't expect to see it on the top of HN on a Saturday
| morning..
| RobotToaster wrote:
| As opposed to pythons who know human?
| fud101 wrote:
| I'm trying to decide between taking a Django job and an Elixir
| one. Can't decide between old and proven and new and early
| adopter. Any advice?
| xutopia wrote:
| Elixir will present you new concepts that you will be
| unfamiliar with and the development experience is actually
| really fun! For becoming a better programmer long term I would
| go for an Elixir experience early on.
| jjtheblunt wrote:
| Elixir : mind expanding -> skills expanding
| 8s2ngy wrote:
| I am in a similar situation as well. The company at which I am
| working as a trainee engineer has a small team dedicated to
| Elixir and Phoenix. I have a choice between Ruby with Rails and
| Elixir with Phoenix after I am done with my training. Elixir
| intrigues me because it is so different from the programming I
| learned at college, but I am also anxious about shoehorning my
| initial work experience into a niche technology that might be
| difficult to find a job in, a few years down the line.
| fud101 wrote:
| Yeah, it's a big trade off careerwise, i'd have to go with
| Django also. I have the lisp disease of wanting a magic
| bullet when none exists.
| elephanlemon wrote:
| Have you written a functional language before professionally?
| If not, I'd lean towards Elixir as a way to expand. Can always
| go back to Python later.
| yurishimo wrote:
| Personally, I would take the Elixir job. Especially if you
| already know Python and have been employed previously. You'll
| learn a totally new way of thinking about problems. Many Elixir
| jobs are also aware that most people don't know Elixir, so
| you'll have plenty of time to learn on the job with plenty of
| support.
| ralmidani wrote:
| My perhaps slightly biased input on Python vs. Elixir (I worked
| with Python for different projects for a couple years, and have
| been using Elixir full-time for ~1.5 years).
|
| Elixir as a core technology for application development (as
| opposed to data science/ML/AI - it's still early days for
| Nx/Axon/etc.) is better than Python in just about every way that
| matters; e.g. immutability by default eliminating whole classes
| (no pun intended) of bugs, having the full power of OTP available
| if you need a distributed system, more convergence around
| libraries and frameworks (to the point that Jose Valim also works
| on Phoenix, LiveView, Nx, etc., not to mention having Mix, EEx,
| and ExUnit built in).
|
| I do wish Elixir had significant whitespace rather than do/end,
| but that's not a hill I'm willing to die on...
|
| My one major gripe with Elixir's ecosystem compared to Python's
| is that, IMO, Django would have been a better source of
| inspiration for a dominant Web framework compared to Rails;
| Django's model layer is top-notch, with all your basic model
| information for an app contained in one models.py file. In Rails
| and Phoenix, you don't get auto-migrations out of the box for
| simple use cases, and your model layer ends up being distributed
| across schema/ActiveRecord files, a "structure.sql" or
| "schema.rb" file, and the migrations. In my real-world use, this
| has been... "sub-optimal" compared to Django, to the point that I
| sometimes dream about building my own Django-ish framework for
| Elixir. Django+Django REST Framework are that good - if you stick
| with Python and are not using them already, do yourself a favor
| and check them out.
|
| Also, Django's admin is old, crusty tech, but it does what it set
| out to do really well.
|
| I will admit Django's implicit queries can cause DB performance
| issues, I wish there was an explicit analogue to Ecto's Repo.*
| functions to force devs to think about when to make the DB call.
| josevalim wrote:
| If you don't mind, I have some questions as I would like to
| learn more. Are you aware of a large models.py for reference
| and learning purposes? Is it expected to define the schema of
| all my models in a single place but none of the logic?
|
| Also, don't you run into scenarios in Django where the
| automatic migration is not enough and you need to provide
| custom commands? In such cases, how do you provide them?
|
| And can you have scenarios where you have two models pointing
| to the same table, but perhaps to a subset of fields (this is
| specially useful in read-only cases)? How is that handled?
|
| Thank you :)
| traverseda wrote:
| >Are you aware of a large models.py for reference and
| learning purposes? Is it expected to define the schema of all
| my models in a single place but none of the logic?
|
| Django models are normal python classes. Depends on exactly
| the logic you're dealing with, but generally you can make
| logic be a method on that class. Try to avoid logic that
| spans multiple tables in general, and if you have logic that
| does span multiple tables you probably want it to be a
| function and not a model method.
|
| There are also signals that get sent on different things like
| model delete/create/etc, but they're to be used even more
| sparingly.
|
| Logic for querying data should probably go wherever you're
| going to use it and you should just pass the model objects
| directly to your views. To start don't worry about optimizing
| queries or the n+1 problem, but as you get more experience
| you can use `prefetch_related` in order to avoid the n+1
| problem.
|
| >Also, don't you run into scenarios in Django where the
| automatic migration is not enough and you need to provide
| custom commands? In such cases, how do you provide them?
|
| You shouldn't generally need to. That said django's migration
| system is very powerful and you can hand-write a migration if
| you need to.
|
| >And can you have scenarios where you have two models
| pointing to the same table, but perhaps to a subset of fields
| (this is specially useful in read-only cases)? How is that
| handled?
|
| I mean you _can_ using proxy models but that 's not really a
| thing with django. Models are for developers and generally
| developers have all the permissions any way, so the solution
| to making a model read only is to just not write to it. If
| you want to present a read-only model to an end user you can
| reference it in a view of make a read-only serializer with
| django-rest-framework. It's python, not java, there's no such
| thing as private/protected members just convention to put an
| "_" in front of things other developers probably shouldn't be
| messing around with.
| josevalim wrote:
| Thanks for the insights, I appreciate it! I will take some
| time to go through the docs and learn more. One last
| question for now (I hope): after the migrations are auto-
| generated, do you check them into version control?
|
| > Models are for developers and generally developers have
| all the permissions any way
|
| To clarify, the reason why you would want to have read-only
| models is rather in complex data model cases or for
| performance reasons. For example, if you have a large model
| with 50 fields, defining a subset with 10 fields can be
| beneficial to performance in several queries. Other than
| that, I agree with you.
| POiNTx wrote:
| Just wanted to say thank you for all the great work
| you've been doing. I'm a recent Elixir/Phoenix convert
| coming from a couple of years of full time Django and it
| makes me so happy to see you being interested in the way
| Django handles models. Imo it's one of the last things
| I'm struggling leaving behind (together with its tight
| integration of the Django admin, which you get for free).
|
| I haven't looked close into Ash but to me it seems their
| approach is interesting and offers a solution, not the
| way Django does it but it is a solution, although a bit
| hard to wrap your head around at first. Django models are
| more simple and straightforward.
| traverseda wrote:
| Yep, you do check the migrations into version control.
|
| >For example, if you have a large model with 50 fields,
| defining a subset with 10 fields can be beneficial to
| performance in several queries. Other than that, I agree
| with you.
|
| Nope, the django ORM has several helpers here. What you
| do in the most basic case is do something like
| MyTable.objects.filter(key__gte=12).only("field1","field2
| ","field3")
|
| Which will (during the initial request) only fetch the
| specified fields from the DB. There's an equivalent
| (defer) for telling it not to fetch those fields during
| the first query.
|
| Of course is someone than tries to access "field4" in a
| template/view django will make an additional query to get
| that extra data.
|
| It's a bit more complicated to make a nice chainable
| filter so you can call `MyTable.objects.only_foo_rows()`,
| you'd need to define a method on a custom object
| "manager", but that still wouldn't generally be handled
| at the model level.
|
| There's also things like select_related,
| prefetch_related, and other tools to make the ORM layer
| more performant. Of course for really exotic things like
| tree-based data structures you can also perform raw SQL
| queries on an ORM object with `MyTable.object.raw("SQL
| goes here")` and have it still return ORM objects. Please
| don't do that though.
|
| For a long time I didn't realize why people were so down
| on ORMs until I tried using a non-django ORM, it really
| does set the bar.
| Alir3z4 wrote:
| > For a long time I didn't realize why people were so
| down on ORMs until I tried using a non-django ORM, it
| really does set the bar.
|
| This. Very much this.
|
| I have given up on one finding such. The closest and
| nicest one that comes to mind is SQLAlchemy. The rest of
| languages or frameworks have indeed nothing compared to
| Django ORM and SQLAlchemy. It's not even fair to compare
| them.
| traverseda wrote:
| Peewee ORM can also be nice if you need support for more
| esoteric DB features (sqlite user-defined table
| functions?). No migrations though.
| spapas82 wrote:
| My experience is also exactly like this. I have a project
| in java/spring and it uses hibernate as an ORM. I can't
| think of how much better is the Django ORM than
| hibernate. When people express hate for ORMs I understand
| where this hates comes from.
|
| If I ever need to do another Java project I prefer to use
| raw jdbc sql than using hibernate.
| josevalim wrote:
| Ack on migrations, tks!
|
| ---
|
| For completeness, you can do the same in Ecto:
| from t in MyTable, where: t.key >= 12, select: ["field1",
| "field2", "field3"]
|
| However, that will still allocate a "MyTable" struct in
| Ecto. And if that struct is large (say 50 fields), slots
| for it are allocated (but none of the actual data on the
| fields).
|
| I am not familiar with Python Object Model enough but, if
| your Python example still allocates an object with slots
| for all 47 other fields besides the three selected, then
| you may still find yourself under circumstances you would
| rather have a "slim" version of the model and reduce
| memory allocation. This may be needed when you need to
| load dozens of thousands of entries into memory for
| processing or similar.
|
| I am not saying this is a must have but I am just trying
| to clarify what my initial comment was about. :)
| traverseda wrote:
| >I am not familiar with Python Object Model enough but,
| if your Python example still allocates an object with
| slots for all 47 other fields besides the three selected,
| then you may still find yourself under circumstances you
| would rather have a "slim" version of the model and
| reduce memory allocation.
|
| Honestly at that point probably don't be using python.
| ORM objects don't use slots, they use a hashmap to look
| up everything every time, and probably that hashmap
| points to a method that points to another hashmap that
| points to some kind of data structure.
|
| If you're worried about that than django probably is not
| for you. That being said it scales out very nicely, you
| probably are not loading dozens of thousands of entries
| in to memory at once but are instead using a celery
| distributed task queue. If you did need to load that much
| in to memory for some reason (presumably some kind of
| data science?) You can use the
| `in_bulk("field1","field2","etc")` query option to return
| raw data as dictionaries/lists instead of ORM objects.
| You don't get the benefit of ORM methods but you're not
| instantiating an ORM object for every row and probably
| for that kind of thing you're better off taking a more
| functional approach any way.
|
| Basically if you're worried about how much memory your
| data is going to take up you probably shouldn't be using
| django, hacking __slots__ or other memory efficient stuff
| into the django ORM is going to be tricky. In that case
| ignore the ORM and just construct your own objects
| directly or use something better suited for that.
| josevalim wrote:
| That's great, thanks for taking the time! Appreciated.
| spapas82 wrote:
| Please notice that nothing stops you from defining a _non
| managed_ (ie Django migrations won 't mess with it) model
| pointing to the same table and having declared only three
| of the fields of the original model.
| traverseda wrote:
| That is more elegant than using a proxy model
| spapas82 wrote:
| The Django docs also mention that https://docs.djangoproj
| ect.com/en/4.1/topics/db/models/#diff...
|
| > If you are mirroring an existing model or database
| table and don't want all the original database table
| columns, use Meta.managed=False.
| Xzya wrote:
| > I am not familiar with Python Object Model enough but,
| if your Python example still allocates an object with
| slots for all 47 other fields besides the three selected,
| then you may still find yourself under circumstances you
| would rather have a "slim" version of the model and
| reduce memory allocation. This may be needed when you
| need to load dozens of thousands of entries into memory
| for processing or similar.
|
| Alternatively you can also tell the ORM to return a
| dictionary rather than a model instance: https://docs.dja
| ngoproject.com/en/4.1/ref/models/querysets/#...
|
| For example, you may get a list of dictionaries with only
| "field1", "field2" and "field3" from a model like this:
| SomeModel.objects.filter(...).values("field1", "field2",
| "field3") [{"field1": "foo", "field2": "bar",
| "field3": "baz"}]
| Alir3z4 wrote:
| Yes. Migrations are checked into the source control.
| They're still the source of truth of the database
| changes.
|
| Regarding read only models pointing to a tabel. It'd
| possible to use proxy models or even non managed models
| where with some mix of Managers it can provide what
| you're looking for.
|
| For getting a subset of fields from a database tabel,
| Django provides ".only()" on the QuerySet which you can
| use to list all the fields explicitly and only them will
| be retrieved. It can even span to foreign field relations
| as well.
|
| Diango ORM is indeed powerful and vrry flexible once you
| learn it. A novice developer can use it quickly and won't
| get in the way. An advanced developer can do very complex
| sfuff with it without touching any raw sql. Still, it's
| possible to write custom sql commands directly.
| neillyons wrote:
| You can use `managed = False` and `db_table` to have
| another model pointing to the same table. `managed =
| False` will stop Django automatically creating schema
| migrations.
|
| eg.
|
| ```
|
| class ReadOnlyUser(models.Model): email
| = models.CharField(max_length=255) class
| Meta: db_table = "users" managed
| = False
|
| ```
| theptip wrote:
| > I mean you can using proxy models but that's not really a
| thing with django.
|
| I think this is over-opinionated. You can use Proxy models,
| and this is a thing in Django. It's not "Django 101" sure,
| but it's not discouraged.
|
| One reason you might want proxy models is if you want to
| only fetch certain columns for a specific type of usage.
| Another common use for proxy models is as a hack to get
| multiple Django Admin pages for the same model (again,
| perhaps pulling different fields or offering different
| views).
| pg_1234 wrote:
| I don't think this is something that will come down to
| technical merits.
|
| Unfortunately it is a popularity contest, where entrenched
| network effects are working against Elixir.
|
| As a Python programmer, I truly believe Elixir/Phoenix is the
| best stack out there from a technical perspective.
|
| However the incredible breadth of libs and resources ... and
| most importantly the mind share (both available devs, but
| more importantly available jobs for seniors who commit to
| Elixir) means that it is still just not a competitive choice.
|
| Almost all commercial software dev is not about technical
| excellence, but rather about applying the available tech to a
| particular business domain. And there Python (and .Net, Java,
| PHP, Ruby ... even Go) are so far ahead that sadly Elixir
| doesn't look like it will make it.
|
| I don't know that anything can be done about this. For all
| that I think Elixir is better, I, like most devs, am not
| about to sacrifice (or even impair) my career for the cause.
| Personal remuneration wins out.
| Alacart wrote:
| That does seem like the same arguments that are made prior
| to just about anything becoming mainstream though. I'm not
| saying it means nothing that python has so much mindshare,
| but the same could have been said to pythons predecessors
| as well. You're right about commercialization not being
| about technical excellence, in the short term. In the
| medium and long term, it's the advantages of recent
| technical excellence that drives a lot of
| commercialization.
| pg_1234 wrote:
| It's also the same arguments that are made prior to
| things falling by the wayside.
|
| Not that I think Elixir will ever fall away, just that it
| won't go fully mainstream.
| ralmidani wrote:
| Hi Jose, thanks for joining the discussion!
|
| The sibling to this post (by "traverseda") is more informed
| and informative than I could hope to write. I will add that
| Django has Manager classes that have default behavior
| included for interacting with the query API, and they can be
| customized to your needs. You can even have multiple managers
| for a given model.
|
| https://docs.djangoproject.com/en/4.1/topics/db/managers/
|
| It's been a few years since I used Django, but I remember its
| model layer fondly, and still follow the framework's release
| processes.
|
| One of the areas where Django lags is being fully async
| (Python imposed a lot of limitations on async operations for
| most of its life). The upcoming 4.2 release of Django is
| laying the groundwork for async DB operations.
| theptip wrote:
| > Also, don't you run into scenarios in Django where the
| automatic migration is not enough and you need to provide
| custom commands? In such cases, how do you provide them?
|
| Data migrations are the obvious case where you need to write
| migration code manually. It comes up in schema migrations too
| on big projects. It's easy to modify the auto-generated
| migration; it's just Python that gets run by the migration
| tool:
|
| https://docs.djangoproject.com/en/4.1/topics/migrations/#dat.
| ..
| dudul wrote:
| Aren't you confusing Phoenix and Ecto here?
|
| I'm familiar with neither Rails nor Django so I dont fully
| follow what you're describing. Are you just talking about the
| difficulty of maintaining the schema/DB mapping with the
| migrations ran against the DB?
| ralmidani wrote:
| I've never used Ecto outside of a Phoenix app, so yes, in my
| mind the line between them was blurry. Thanks for pointing
| out my mistake!
|
| A very recent real-world challenge I ran into was having to
| coordinate updates and diffs to all the files involved and
| keeping them in sync while doing local development (before
| deployment but also while working on fixing a very subtle
| bug). Every time I changed the migration file (even to add an
| index), I had to remember to checkout the previous version of
| "structure.sql" or the migration wouldn't be run, even during
| a complete DB reset (structure.sql is used to know which
| migrations have been run and synced with the SQL dump). Also,
| the schema in Ecto does not have a complete validation API,
| so you'll need to do those in "changeset" functions. Overall
| I like Ecto, and part of me regrets letting myself get
| spoiled by Django's model layer and DB tools.
| josevalim wrote:
| It is totally fine to get spoiled if you consider it is
| better :D
|
| Your case about structure.sql is interesting. It would be
| nice if we could automate it somehow but, if we simply
| tried to re-run a changed migration, then the migration
| would likely fail because the other operations in it (such
| as adding fields), you already exist, no?
|
| Do you have any suggestions/ideas on how to tackle this? We
| could have a "mix ecto.migration.fix" that reverts the last
| migration, wait until you close/save the file, and migrate
| again, but I am not sure how useful it would be. How would
| Django approach this? If you auto-migrate and then do
| further changes, does it change the existing migration or
| does it generate new ones?
|
| PS: the changeset functions are pretty much on purpose
| though. It is important to decouple the validation from the
| schema because a single schema can have several validations
| rules (and they can diverge overtime!).
| bostonvaulter2 wrote:
| Hmmm, if we're willing to accept a dependency on git than
| it might be interesting to write a `mix
| ecto.migration.rerun` that rolled back any migrations
| that are untracked or dirty according to git, then re-ran
| them. That would simplify a pain point I encounter when
| I'm iterating on a migration because sometimes I rollback
| too far accidentally and finding the right argument to
| rollback feels like a chore. The nice thing is that could
| be prototypes outside of ecto quite easily.
| ralmidani wrote:
| Django's approach is to run all the migrations, from the
| migration files, if the database gets wiped clean. In
| other words, if you're developing on your local machine,
| you can just drop the DB and start new (or if using
| SQLite, just delete a file), and after running
| migrations, you never have to worry about whether all the
| necessary files are in sync with the database. As Neo
| might say:"there is no spoon..." seriously, structure.sql
| is simply not needed, so you won't find yourself making
| creative use of git reset/checkout on a specific file as
| you're iterating.
|
| To answer an earlier question you had, Django's
| "makemigrations" command tries its best to help you avoid
| having to manually edit migration files; if you rename a
| field in models.py, it's usually smart enough to ask you,
| at the command line, if you renamed it, and proceed to
| make the migration file for you. Of course, for advanced
| migrations the command can only take you so far, but
| again, if you're trying to iterate quickly, you really
| need to experience Django's ORM and DB tools to be able
| to appreciate them fully.
|
| Regarding changesets, I love the functional API, and at
| the same time I wish we could automatically derive a
| "default_changeset" function from the schema itself for
| straightforward cases, and then let devs run diverging
| validations in their own changeset functions. Maybe an
| interesting idea to explore with a macro?
|
| By the way, I'm a huge fan of your work, and hope I get
| the opportunity to work with Elixir for a long time. Any
| criticisms or comparisons are to try to bring
| improvements to the ecosystem I love. :)
| josevalim wrote:
| Thanks! FWIW, structure.sql is not needed in Ecto either.
| You must do that when:
|
| 1. You want to start discarding migrations (because you
| have too many) 2. You had an existing database
|
| Are those never a "trigger" on Django side? I appreciate
| the opportunity to learn!
| ralmidani wrote:
| TIL you actually don't need structure.sql for Ecto! In
| that case, discarding migrations on a large running app
| seems like a not-always-good practice, right? FWIW, my
| experience with Ecto has always been in joining existing
| codebases that are already big.
|
| I do also want to add that Django can kind of do the
| reverse of auto-generating migrations: it can "inspect"
| an existing database and generate Python classes that
| allow you to use the Django API as if you wrote those
| classes yourself:
| https://docs.djangoproject.com/en/4.1/howto/legacy-
| databases...
|
| Of course, the feature is not going to be perfect,
| especially if a team has been using odd naming
| conventions in the legacy database, but it seems helpful
| at least in theory.
| bostonvaulter2 wrote:
| Inspecting a database and coming up with models is a
| frequent pain point that I see new elixir devs
| experiencing. I'd love to see someone take a stab at
| generators for that. I wonder if someone would do an
| integration for https://ash-hq.org/ that does that.
| maxmorlocke wrote:
| Generally speaking, it's inadvisable to 'discard'
| migrations with django. If the migration set is getting
| too large, the general practice is to 'squash'
| migrations, which is a django-supported function for
| merging the migrations down to a single app. You can do
| the less blessed, but more simple function of nuking the
| migrations, updating the migrations table, and remaking
| your migrations... but you have to coordinate that in
| every environment.
|
| For an existing database, you can easily create django
| models for each table, etc. There's a --fake option to
| update the migration table to make it think you've
| applied these migrations, but not actually apply them.
| This convinces django you've brought the database in
| sync. May your deity or deities help you if you did not
| actually bring it in sync. I've used this quite a bit in
| some java ee->python migrations I've done in the past.
| di4na wrote:
| Note on Ecto: the macro based syntax was not exposed at first but
| ended being public API because everyone used it to be able to do
| pipelines and complex composition.
|
| I scarcely use it but it does clean up stuff sometimes.
| meanmrmustard92 wrote:
| I like how programming language article/book title cliches are
| cross-pollinating now. In a decade, I hope we'll have "Bite size
| julia for morons who know how to stand on one leg and can read
| perl"
| RandomWorker wrote:
| As someone that is deep into a Python web development, I see
| where this can be useful. However, after 1/3 down of the article
| it gets harder and harder to wrap my brain around the concepts
| without really learning elixir syntax. I feel like it would have
| been better to have 10 smaller articles than this long one, going
| deeper into the syntax and showing other example of Python way of
| doing it. I'm not sure I would do some of the example in Python
| as the author suggested. That case case it just build a string
| array and use join. To creat the statement with an eval to run
| it. Weird I know, but I've pulled that trick a couple of times
| now.
| Mizza wrote:
| Author here. This blog post originally started out as just
| notes to myself as I was learning the language, so it's
| basically a brain-dump wrapped in a little prose to give people
| some exposure to the language. I still love Python, but I think
| Elixir is a great tool to have in the toolbox.
| RandomWorker wrote:
| Hi there commenter here. Thanks for writing the article, I
| will return on it maybe in a year or so. I started learning
| Clojure this year and it's quite a journey. But functional
| programming is the future I'm convinced. Cheers.
| Timothycquinn wrote:
| Interesting article. Having the built in Redis via ETS is slick.
|
| I currently use Python but don't use Django but instead wrote my
| own WSGI frameworks based on Flask Restx. I'm not a big believer
| of ORMs besides their CRUD functionality so there is not much
| benefit for me using Django and the security burden it carries
| (like PHP) by being so popular. I can keep my designs light
| weight, very secure and fast; albeit not nearly as fast as
| Phoenix.
|
| Note however, I don't build public facing high performance
| applications so its not critical to have max IO like that which
| Phoenix can handle.
|
| In a way, I wished I had moved to Elixir but with the technical
| debt invested in Python its a very big jump. Maybe someday down
| the road...
| spapas82 wrote:
| > Interesting article. Having the built in Redis via ETS is
| slick.
|
| This isn't really true. Although having a built in redis may be
| possible, the fact is that production elixir projects _do_ use
| redis on a lot of cases (for example as a task queue). ETS is
| rarely used because of its complexity.
| sph wrote:
| Redis might have a nicer API but the ops of maintaining
| another service is not simpler than just using ETS that is
| built in the platform.
|
| I'd rather choose Redis only iff I hit the limits of ETS. And
| 99% of apps won't even get to that point.
___________________________________________________________________
(page generated 2023-02-25 23:02 UTC)