dogweather

dogweather

After using Elixir for a long time I can’t wrap my mind around Python’s APIs.

So with the help of functoolz curry, flip, and pipe, I can write HTML parsing code like this:

    def parse_title(dom: XmlResponse) -> Title:
        name = pipe(
            dom
            , html.xpath("//TITLE-TEXT") 
            , text.titleize
        )
        number = pipe(
            dom
            , html.xpath("//TITLE-NUM")  
            , text.split(" ")                  
            , seq.get(1) 
        )
        children = _parse_divisions_or_articles(number, dom)
        url      = _source_url(number)

        return Title(name, number, children, url)

I’m not re-writing any of these functions. I’m just wrapping each of them with a little code to give them a consistent interface. And once they each have this new API, they can be easily chained together.

Anyone else adapting other languages to the Elixir fluent API style? I don’t get much love from the Python community when showing this kind of code. :smile:

Showing Posts 1 to 8

kokolegorille

kokolegorille

I think You would get the same kind of love from the Elixir community when showing Object Oriented Elixir code :slight_smile:

Eiji

Eiji

Definitely no! In programming that’s the only one thing I call my personal anti-pattern (i.e. that’s my opinion without linking to some resources). I’m 100% against forcing solutions known from other languages in a way you wrote. Simply, every language is different. It have other styles and expectations. There was a talk about pipes in Erlang, but it was hard to implement, because in Erlang the data we work on is in the last function argument instead of first. Forcing Elixir-like pipes into Erlang have no sense as simply there would be no reasonable use case.

Speaking generally the problem often is not what you do, but how you do. You can force other language features and deal with expected hate or write a new features inspired by other languages. It’s not shame for others to improve, but nobody would agree to change habits because something is better in other languages. Same goes for law. You do not force law articles from country you born as it’s simply stupid. However you can instead propose changes to existing law system.

That’s endless topic i.e. assimilation vs integration

ivanov

ivanov

I got to attend the annual American Geophysical Union (AGU) fall meeting that was in San Francisco a few weeks ago, thanks to a pass from Matt Rocklin (author of functoolz and also dask). Someone there was also sharing similar positive sentiments about this kind of chaining, and said how it felt functional and Lisp-like, to which Matt responded something like “that’s exactly why I built it, I was re-writing in Python pieces that were missing for me that I was used to having in Clojure”.

I’d call it cross-pollination :slight_smile:

sodapopcan

sodapopcan

Hello and welcome to the forums!

I have nothing wrong with cross-pollination so long as its adopted by a language’s community as a whole. I also whole-heartedly applaud doing experiments. But I’m otherwise with @Eiji’s here. Coming across business code that someone decided to write in an idiom completely foreign to the language I’m working in is the worst. I’m actually getting a little worked up thinking about the several times this has happened to me :cold_sweat:

Is that how it’s ", ".join(["Hello", "World!"]) or something? I’ve heard Pythonistas say this makes more sense (somehow). I honestly don’t know much Python, though!

dogweather

dogweather OP

That’s very even-handed and balanced—a hard act for me to pull off. :slight_smile:

I don’t think it’s language design differences. I attribute it to their ages: Python is decades older than Elixir and it carries some baggage:

  • Parts of Python core are fluent (Elixir pipe-style) api’s, read left-to-right.
  • Other core libs require a right-to-left function-invocation style reading.

I’ve researched this deeply and the best I can see is, Python’s battling paradigms are present due to historical reasons.

In contrast, Elixir was designed with advantage of seeing was Python, Ruby, etc. did well and not so well. Ruby, in turn, was designed looking at Python. Even though everything in Python is an object, method chaining couldn’t be universally applied. Ruby sought to correct that in its design.

dogweather

dogweather OP

I totally agree. I would never produce code like this for a client. This is my personal indie project, and I prioritize my productivity.

Doh! yeah, it’s join() that kills me. It’s implemented only on string objects, not on lists or iterators.

I want to break up and refactor code where it’s meaningful. Not because a decision made in the 1980’s hasn’t been overturned. I like thinking about language design, and ponder these issues.

Concrete example from my code

I found this in about 3 minutes of looking. Incredibly, I see four different paradigms present in this one section of code. (!)

    # Return an HTML document's plaintext, cleaned up.
    raw_paragraphs         = rule_div.xpath("p")[1:].getall()
    cleaned_up_paragraphs  = [p.strip().replace("\n", "") for p in raw_paragraphs]
    cleaned_up_paragraphs2 = [re.sub(r" +", " ", p) for p in cleaned_up_paragraphs]
    non_empty_paragraphs   = list(filter(None, cleaned_up_paragraphs2))
  • Line 1: Fluent, chained method calls
  • Line 2: Mixed modes: A list comprehension containing chained method calls
  • Line 3: Mixed modes: A list comp containing a namespaced core regex library call
  • Line 4: A right-to-left “chain” of global function calls.

The worst part of this, for me, isn’t the poor maintainability from the need to shift between different styles. It’s that these “semantic roadblocks” of intermediate variables were essentially forced on me by the paradigm changes.

E.g., global replace is a string method when the pattern is a string. When the pattern become a regex, it’s now a library call conventionally namespaced with re.. So whatever data flow you were coding needs to shift paradigms due to this implementation detail.

Ruby (really, Matz) saw this, and fixed it by simply making String.sub() accept either a string or regex pattern.

Eiji

Eiji

Ok … wait, no! That’s not “ok”! :sweat_smile:

Umm … I never know Python is so … well … Why do “we” force it for children in schools? What do “we” teach them? :smiley:

I heard Python is good for beginners, but now I see something else … XP - memes are too old for “young blood”:

“WindowsXP or better” - so Linux will do the job!

so they decided to introduce new one:

“Required 10 years in Python or better” - so 1 day in Elixir will do the job!

Now I better understand why Python community does not like your idea. The 5th paradigm would be a hell for them even if it’s Elixir’s paradigm. Please let them rest at least for now at the start of 2024. :joy:

Happy New Year! :fireworks:

dimitarvp

dimitarvp

This should be qualified with context: many people said that learning an immutable FP language made them write more understandable, clearer, easier to read, easier to debug and test code in imperative OOP languages.

It’s not about trying to make Python stand on its head. It’s about writing Python that is… less ugly and hard-to-work-with Python.

Languages should indeed cross-pollinate as @ivanov said.

One prominent example: after Rust made enums (sum types) prevalent in compiled languages – nevermind that OCaml and Haskell had them for ages before that but oh well :003: – then many people started wanting them in other languages.

— All posts loaded —

Where Next? Top

Trending in Discussions Top

AstonJ
As the title says, please share what you’ve been up to with Elixir. Whether that’s been learning it, looking into it, making stuff with i...
2977 92995 915
New
AstonJ
The obligatory hello world thread! Who are you and where are you from? :stuck_out_tongue:
4616 55835 594
New
caslu
I want to open this thread for you all to discuss and help those who really like Ash but are still hesitant to use it in a real project. ...
New
Herve37
We’re evaluating API mocking tools for OpenAPI-based projects and would love to hear what other teams are using. We’re particularly inte...
New
matt-savvy
Is there a word for the ~> symbol used in Version strings? Do you also just call it a Squiggle Arrow™ ?!
New
GES233
I’m posting this in response to Jose’s recent tweet (Cr. link) : People are sleeping on Elixir for a coding harness: Hot-code swappi...
New
nseaSeb
AcmeScript — Writing JS hooks as if I were still using Elixir I’ve been having fun building a little something over the last few days: Ac...
New

Other Trending Topics Top

garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
wintermeyer
There are three potential reasons for members of this forum to have a look at https://vutuv.de You are tired or annoyed of LinkedIn. Yo...
New
webofbits
Aludel - LLM Evaluation Workbench Aludel is an embeddable Phoenix LiveView dashboard for evaluating and comparing LLM prompts across mult...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews