HNHacker News
TopNewBestAskShowJobs

ricketycricket

338 karma · joined September 18, 2015

submissionscomments
ricketycricket··on Things I like about Gleam's Syntax
Looks like it is an external library[^1]. Readme states it is experimental and lists some limitations.

[^1]: https://github.com/gleam-lang/otp

ricketycricket··on Things I wish I knew before moving 50K lines of code to React Server Components
You are wholesale calling people ignorant over a technology decision.

> When disagreeing, please reply to the argument instead of calling names. "That is idiotic; 1 + 1 is 2, not 3" can be shortened to "1 + 1 is 2, not 3."

ricketycricket··on How to implement a disk cache plugin for Elixir's Req HTTP client?
> no error checking at all (I assume it just panics or exception?)

In Elixir, bang functions per convention will raise on error. `get/2` will return error tuples allowing you to handle errors. In fact, get!/2 just calls get/2 and raises for you[^1].

> no mention of JSON at all

Req is the most "batteries included" Elixir HTTP lib out there. I can't speak for Wojtek, but I believe the goal was to make Req extremely easy to use in scripting or things like LiveBook without having to do much work. That being said, the automatic decoding is mentioned in the readme[^2] and the docs[^3].

> if "body" is JSON, how do you even get the raw body, or can you?

Per the docs[^3], you can either skip with the `:decode_body` option, or just build your own request using only the steps you want.

> just seems over engineered/over fitted whatever you want to call it.

Fair, but again, this library is designed to be on that end of the spectrum. There are plenty of other libraries further down the stack that you can use. I am partial to Finch[^4], upon which Req is built.

To address the sibling comment about "Let it Crash", the language allows you to easily recover from crashes, but that is for resiliency, not error handling. In practice you would use the non-bang get/2, pattern match on the response, handle any errors, perhaps use Kernel.get_in/2 to safely traverse the map, etc. The example provided by the author is not "production ready".

[^1]: https://github.com/wojtekmach/req/blob/v0.3.11/lib/req.ex#L3...

[^2]: https://github.com/wojtekmach/req

[^3]: https://hexdocs.pm/req/Req.Steps.html#decode_body/1

[^4]: https://github.com/sneako/finch

ricketycricket··on From Python to Elixir Machine Learning
Recommendation seconded. I'm only to chapter three due to time constraints, but it is well written and approachable for someone lacking ML experience.
ricketycricket··on Elixir for Ruby developers: the three most important differences
davidw is right that ports are somewhat limited, but I haven't had much trouble doing what I need with FFmpeg in particular. I used the bash wrapper from the docs for Port [^1] and it has worked well.

When a stream starts I start a supervisor that then starts a GenServer to manage the port. On init a port is started for FFmpeg (using the above bash wrapper) with args that sends 16-bit PCM audio back to the port through the `handle_info/2` callback.

When a new live HLS segment is downloaded by FFmpeg the entire segment's audio is sent to the GenServer all at once (could be a few handle_info/2 calls, but it happens quickly). Since I want to work in small fixed chunks, I send the segment's audio to an AudioBuffer GenServer (started as a sibling under the same supervisor). This buffer uses binary pattern matching to segment the audio in chunks exactly 2 seconds long while keeping any remainder in the GenServer's state for the next buffer event. I then send the chunks to another ChunkBuffer GenServer that pops chunks at 2-second intervals for processing.

Since everything is supervised, if (when...) FFmpeg crashes the supervisor just restarts it. Meanwhile, the audio in the buffer is still processing and nothing goes down. There might be a duplicate word or two in the transcription if the restarted port processes a segment again, but everything keeps running smoothly.

For even more reliability, I have the application running clustered across four locations in the US, EMEA, and APAC using libcluster[^2]. The stream supervisor is started under a Horde.DynamicSupervisor[^3] with a custom distribution strategy. The strategy prefers the region closest to the company HQ, but if it goes down, the processes will be restarted in another region.

[^1]: https://hexdocs.pm/elixir/1.13.4/Port.html#module-zombie-ope...

[^2}: https://github.com/bitwalker/libcluster

[^3]: https://github.com/derekkraan/horde

ricketycricket··on Elixir for Ruby developers: the three most important differences
Just wrapped up a live translation feature that watches an HLS live stream, live transcribes with whisper and then translates into 18 languages. Heavy use of OTP: supervision trees for each stream, ports for managing ffmpeg and receiving audio, async tasks for concurrently submitting chunks to translation API, etc. Transcription and translations provided in real-time via LiveView to about 4,000 viewers.

Little over 3 weeks from `mix new` to the live event. Not sure how I could have done it so easily without OTP and LiveView.

ricketycricket··on When Work Didn’t Follow You Home
The problem is that you are saying two different things in your replies. On one hand you say that you aren't suggesting that people work for free, and on the other hand you say that people leaving when their shift is over should not be rewarded with raises.

If employees are being paid to stay after 5 or be on call, then their shift isn't over. If they aren't being paid for their time, they absolutely should go home. If the product cannot afford to go down, the company is responsible for keeping paid staff on hand. Expecting people to work beyond the agreed amount and punishing those that don't by removing opportunities for advancement is reproachable. It may be the norm, but it shouldn't be.

ricketycricket··on Tailwind and the Beauty of Ugly Code
> A modal log in screen is five elements: a shade, a dialog, two labels, two inputs and a button. These are all very easy to name.

Agreed. But why name them at all if the structure is so simple? Keep your simple, understandable structure, colocate your styles with tailwind classes, and avoid the unnecessary cognitive overhead of naming obvious things (is it .username or .user-name?) and linking them with remote styles in a different file.

Not saying it’s the “one true way”, but I don’t think your way is necessarily simpler.

ricketycricket··on Amount of work that once bought an hour of light now buys 51 years of it (2017)
Not to mention the fruits and vegetables required for a balanced diet. Prices for produce in my area have gone through the roof. What about the family of four, the single parent, one of the many recently let go? The cost of basic goods and services has inflated as well, meaning less money for food. Sure, maybe there are people spending way too much eating out, but food scarcity is a real problem for many. And just saying you should be able to afford it and throwing around made up $ figures doesn't solve a thing.
ricketycricket··on How to sell Elixir again
As one of those others, I can confirm this is indeed still true as of Phoenix 1.7. `--no-assets` will not add any CSS or JS to the project other than empty `app.js` and `app.css` files in `/priv/static/assets` for you to fill in yourself if you want. You are completely on your own to implement an asset pipeline of your choosing. Of course, if you want LiveView you will have to bring some JS back in.
ricketycricket··on How to sell Elixir again
Of course, each case will be unique. I heavily optimized with temporary assigns so the message lists would not be persisted in server memory. This is even better now with the new streams functionality. The knobs to tweak are there.
ricketycricket··on How to sell Elixir again
I do exactly this. Elixir supervises Ports to python and C binaries and manages all the communication between processes including buffering and maintaining state when necessary. Using libraries like Horde even allows you to run these processes on remote nodes very easily. It has worked fantastically well.
ricketycricket··on How to sell Elixir again
> Almost every system scales simply vertically, vertical scaling is (to a first approximation) throwing faster hardware at the problem. If you're IO bound you get a faster IO bus (this is not necessarily easy to do, but if you do it the system scales to the limit of it). If you're CPU bound you get a faster CPU. And so on.

My interpretation was vertical scaling is within a single node and adding cores or CPUs to a single node is vertical. Multi-core and multi-node really present similar problems, so adding more cores or adding more nodes isn't terribly different from a design perspective.

> ...easy to scale horizontally by tacking on additional CPU cores or physical CPUs.

If you define adding more cores to a single machine is actually horizontal scaling, then we agree in principle, just not in the definition of scaling.

ricketycricket··on How to sell Elixir again
After wondering this myself, I finally just went all in on LiveView and was extremely surprised at how efficient it was. I have had over 4,000 concurrent users on a single LiveView with real-time messaging, streaming transcriptions, viewer counter updates (don't use presence for this), and the typical interactivity (signing on, navigating, etc.). On a single 8-core machine it maxed at 20% CPU during the few minutes everyone was signing on (via OAuth) and idled at less than 5%. RAM never exceeded 900MB. I've since distributed the same application into EMEA and APAC to provide better latency for those users (which takes libcluster and about 20 lines of config to set up), and zero problems with that either.
ricketycricket··on How to sell Elixir again
Both vertical and horizontal are pretty simple with Elixir and are done in essentially the same way.
ricketycricket··on The future of generative AI is niche, not generalized
Maybe diagnosis assistance, but I was specifically responding to the idea that the AI may deliver information. The risk that this information may not be correct even 0.01% of the time will be considered unacceptable from a legal and regulatory perspective. A PDF surgical technique can be guaranteed to be accurate.
ricketycricket··on The future of generative AI is niche, not generalized
I work in a field related to surgeon education. Until the results of AI output can be guaranteed to be deterministic and proven to always be correct, the legal ramifications of an AI providing incorrect information or promoting off-label usage is likely insurmountable. There are dozens or hundreds of eyes that see this information before it is approved for use and weeks can be spent arguing over a single word.
ricketycricket··on RedPajama: Reproduction of LLaMA with friendly license
I'd guess it's the book Llama Llama Red Pajama: https://openlibrary.org/books/OL24377652M/Llama_Llama_Red_Pa...
ricketycricket··on Distributed Machine Learning Notebooks with Elixir and Livebook
This one? https://github.com/lawik/membrane_transcription
ricketycricket··on Distributed Machine Learning Notebooks with Elixir and Livebook
> I believe Lars is going to do a cool demo with Membrane and ML at ElixirConf EU next week.

Yes, the relevant part of his demo with the membrane pipeline appears to be here: https://github.com/lawik/lively/blob/master/lib/lively/media...

ricketycricket··on Alpaca: A strong open-source instruction-following model
You mean the AI content trained on human input?
ricketycricket··on Bumblebee: GPT2, Stable Diffusion, and More in Elixir
I don't have the ML chops to make it happen, but whisper would be insanely useful to have in the tool chest.
ricketycricket··on Elixir – Phoenix LiveView Native
It is not on the phone, no. I'm sure eventually you could run it on the phone like Elixir Desktop[1], but that isn't what it is at the moment. The phone connects to the server via a websocket and the SwiftUI "DOM" is pushed to the client just like HTML would be. In fact, I already built a hybrid Web & Native demo[2] that demonstrates that it's just bog-standard LiveView.

[1] https://github.com/elixir-desktop/desktop

[2] https://natetodd.com/building-for-web-and-native-with-livevi...

ricketycricket··on Elixir – Phoenix LiveView Native
Yes, that is what it is.
ricketycricket··on LiveView Native
There appears to be a good getting started tutorial available at https://liveviewnative.github.io/liveview-client-swiftui/tut...

Between this new project, "regular" LiveView, Nx, Livebook, and FireFly, the Elixir ecosystem is expanding at an impressive rate.

ricketycricket··on Double Commander
I've been happily using Forklift for years. https://binarynights.com/
ricketycricket··on Web Push for Safari
> Note that browser push notifications also work on mobile, so you don't need to install an app to get real time alerts.

Push notifications in Safari are only supported on desktop for now.

ricketycricket··on Erlang/OTP 25.0 Release
1.13.4 is verified on OTP 25 RC2, so I'd assume it supports the release OTP 25.

See: https://github.com/elixir-lang/elixir/releases/tag/v1.13.4

ricketycricket··on Erlang/OTP 25.0 Release
I mean, `mix phx.gen.release --docker` generates a nice dockerfile for packaging up a release (which is all Fly does). At that point it's essentially no different than any other containerized application. I've shipped Elixir apps to Heroku, Fly, Render, and Azure with basically no devops on my part.
ricketycricket··on DigitalOcean: New $4 Droplet and updated pricing
Pricing page still shows current prices. It appears to be a roughly 20% increase across the board.
← PreviousPage 2 of 4Next →