HNHacker News
TopNewBestAskShowJobs

linkdd

2,632 karma · joined June 19, 2019

email: david.jose.delassus@gmail.com

  - https://link-society.com
  - https://krouter.cloud
  - https://flowg.cloud
  - https://linkdd.github.io
  - https://david-delassus.medium.com
submissionscomments
linkdd··on Astmaker – A DSL in Rust for programming language designers
Just for the record, this will also bypass the monetization I get from my articles. But I don't mind, thank you for sharing this so more people can read my work.

I'll keep publishing on Medium though :)

linkdd··on Astmaker – A DSL in Rust for programming language designers
Then don't, I'm not forcing you.

I use Medium because I can monetize easily the articles I write, though it's not much (currently around 10-15$/month).

I'm not doing it for the money, but it's still nice.

linkdd··on Astmaker – A DSL in Rust for programming language designers
The rust-analyzer extension for VSCode is quite good for this.

Though, I should try to use `quote_spanned!` instead of `quote!`, but I'm kind of a newbie with proc-macros.

As for your take on the visitor pattern. In my previous code, I had the `visit_expr`, `visit_stmt`, etc... And it's a lot of boilerplate, I wanted to reduce the amount of copy/paste and facilitate refactoring, hence my DSL.

I do have multiple phases during compilation where I walk the AST and the "only" difference is the return value of those `visit_*` functions and their body. Here, I just have to use a `model!{}` macro for each "phase", which is less boilerplate code.

In the end, it's just static dispatch through the use of a trait that I called "Visitable".

linkdd··on Astmaker – A DSL in Rust for programming language designers
HN removes the friend tag in the URL so I can't share the "no-paywall" link unfortunately.

Though, this is fine by me. I don't mind people bypassing the paywall, but it's a source of (rather small) income for me :)

linkdd··on Ask HN: What is the license of GitHub's blog and The README project?
Thank you. I ended up contacting the author who gave me permission quite quickly :)
linkdd··on Ask HN: What is the license of GitHub's blog and The README project?
I consider "no response" to be a negative answer by default :)
linkdd··on Ask HN: What is the license of GitHub's blog and The README project?
I sent a mail an hour ago to the author of the article. There is no "answer I don't like", if I'm not allowed to do it, then so be it.

Please don't assume things when you don't know the person.

linkdd··on How we hack Hacker News and consistently hit the front page
> ... so you can try the same post again. Don’t overdo it. I would say max 2 or 3 times.

I don't even understand how that's possible. Every time I tried to post a link that was already posted (by me or someone else), it redirected me to the original post (and upvoted it if I wasn't the author).

After observing that behavior 2 or 3 times, I assumed HN had some kind of deduplication system.

linkdd··on How to sell Elixir again
The problem is that the code generation tools does not let you learn the different parts. On top of that, all the documentation around just tell you to use the codegen tools and unless you go look at the API reference (or the source code directly), there are no resource to learn the different parts.

Take a look at how django does it. `django-admin startproject` creates:

  - settings.py
  - wsgi.py
  - asgi.py
  - urls.py
Then you just need to add your models and views. There is the `startapp` command, but you don't really need it.

Even with the codegen tools, you still need to learn what a plug router is, what a phoenix controller/view is, what an ecto repository is, etc...

The codegen tools just overwhelm you with irrelevant code (i'm making an API, why the hell do you generate static files? and why do i need to edit so many files to take it out?)

Another point I don't like about Ecto is that you can't easily switch the database backend depending on the environment.

With django, I can have an sqlite3 db for the dev environment, and a pgsql one for the production. I don't want to run a docker image for pgsql on my machine. I just need to read the DATABASE_URL environment variable, and the ORM takes care of the compatibility. If later on I need some specific pgsql feature, I will have to run the docker image on my computer anyway, but until them please keep the complexity out of my way.

linkdd··on How to sell Elixir again
The thing I don't like with Elixir/Phoenix is the code generators.

I hate code generators with a passion. They obfuscate the inner workings of the library. Have you tried to find a tutorial which do not use the Mix task "phx.new"? (an up-to-date one).

For example, if I need an API, I will pass `--no-assets --no-html --no-live --no-mailer --no-dashboard` and the generator still creates a static files folder and static files related code.

If I want the strict minimum, I have to take some time to remove the un-necessary code.

Don't misinterpret me, I think Phoenix is a great framework, just like Python/Django, and Ruby on Rails are.

But sometimes, I just want Flask/FastAPI. You can say "just use plug_cowboy", but IMHO, "plug_cowboy" is more like "express.js", not really a FastAPI-like framework.

Also, absinthe is the only GraphQL implementation that natively supports subscriptions (via phoenix+phoenix_pubsub). In Django (graphene), you need so much more boilerplate with django-channels and yet another library. In JS land, Apollo Server also do not support it natively, you need graphql-ws and a pubsub implementation as well. And most of those pubsub implementations will need a Redis (or whatever) to distribute the queue between multiple web workers, while Erlang/Elixir have been designed for this (which actually simplify your infrastructure).

In the end, I often go with Django Async (via ASGI) with Server-Sent-Event (via an async StreamingHTTPResponse) to avoid the complexity of GraphQL subscriptions. But even that, I need a pubsub via Redis to make my multiple workers aware of each other. While with Elixir, a simple libcluster dependency, and a `receive` in the endpoint handler would be enough :)

linkdd··on How to sell Elixir again
> How many platforms can realistically promise this?

I love the OTP framework. So much that I suffer from "erlang envy" in every other language I'm using.

Which is why I made this a couple years ago: https://linkdd.github.io/triotp/ (not benchmarked, not tested in production, only an experiment)

linkdd··on How to sell Elixir again
The "let it crash" philosophy has a misleading name. It's not "don't handle errors", but it's "delegate the error handling to a component dedicated to this".

With OTP, you have what we call a "supervision tree". Your software is divided into components (erlang processes) and organized in a tree where the leafs are your components, and the nodes are the "supervisors" which will catch the error, and restart/retry the operation.

What's the result? Imagine you have a component that is polling data from the database and then sending a message to another component based on that data. For a split second:

  - there is a network error
  - you lose the connection to the database
  - the component crashes
  - its supervisor notice the crash, restart the process
If the network error was temporary, everything goes back to normal, and your system did not stop for a temporary network error. And your component does not need to have "retry code" (it is delegated to the parent supervisor).

If the network error was not temporary, the parent supervisor will notice that the component crashes far too often, and will decide to crash as a result. Letting the parent supervisor of the supervisor deal with the problem.

In Erlang/Elixir, processes can "monitor" other processes. They will receive a message when the target processes dies (normally, or abnormally). This allows you to delegate the error handling so yes, you write less defensive code, because that code is located in a dedicated component that will be notified automatically.

linkdd··on New C features in GCC 13
Meh, I compile with -Werror :)
linkdd··on Error Handling Patterns
It's missing the Erlang/Elixir pattern of returning a tuple `{:ok, T}` or `{:error, E}`, where we can then use pattern matching, or `with` expressions, etc...

To be fair, it is very similar to a `Result<T, E>` type, which is why I made this library a while ago: https://github.com/linkdd/rustic_result

linkdd··on Rust's Poor Composability
The problem with .map().collect()? is that it does not short-circuit.

Consider:

  for item in iterable.iter() {
    item.foo()?;
  }
You will exit the loop as soon as there is an error. But with .map().collect(), you iterate over the whole list, and then exit if one of the items yield an error.

EDIT: Thank you for your answers, it seems I was wrong and it does short-cricuit!

linkdd··on Best courses to learn 2d game development in C++?
"I want to learn C++" -- "Try Godot"
linkdd··on Was there a tech-hiring bubble? Job postings data suggest so
It's kinda the same for me, our product solved a problem that was not enough annoying to people for them to consider buying it, so we never had the product market fit, and never managed to sell a single license. The company still exists today, but it's mainly surviving with us doing freelance work and hoping one of our side project might generate some revenue.

Maybe as open-source, the product could have some success, but I don't know how to "sell" open-source or make a revenue from it.

linkdd··on Was there a tech-hiring bubble? Job postings data suggest so
> Individual engineers prove over and over again that they can start multi-million dollar businesses

Beware of survivor bias, for every successful business, there might be a 1000 failed ones.

linkdd··on Cities: Skylines II
> and cars magically disappear

Not with the Traffic President mod which allows you to disable cars despawning and adds to the challenge of building a good transit system.

linkdd··on Writing a simple Lisp interpreter in Rust
After the translation of the source code to AST, I have walk through the AST to validate the code as much as possible.

The generated Rust code should be valid Rust code that compiles with no error. I only have 2 exceptions to that rule:

---

Function calls:

I haven't found a way to verify that the identifier used resolve to a function with the correct signature (it would need some sort of partial evaluation and static type checking I don't have).

Rust FFI:

Letlang will have the ability to call native Rust functions (allowing me to rely on the Rust ecosystem to implement the stdlib), but it expects functions to have a specific signature.

---

Those are the 2 cases where `cargo` can throw an error. So I (plan to) include source mapping comments in the generated Rust code. After getting the output of `cargo` as JSON, I can identify the error type and location, then using the source mapping info, I can pinpoint what AST node generated the wrong code.

On a semi-unrelated note: Every Letlang module is a single Rust crate. The compiler generates a cargo workspace, and a cargo project in that workspace for every module. It makes dependency management (and my life) easier.

It's funny how people are intrigued by my choice of targeting Rust, while other compilers targets C, Javascript, or other higher-level languages :P

But I guess it's because I use the term "compiler" and not "transpiler". Hint: I hate the word "transpiler", which is just a synonym to "compiler" IMHO.

linkdd··on Writing a simple Lisp interpreter in Rust
This makes implementing the runtime (I use tokio for the concurrency model) faaaaaaar easier.

I also get the borrow checker, move semantics, etc... that I would have to implement myself if I were to target LLVM IR.

That question has been asked so many times, I should probably start a FAQ :P

linkdd··on Writing a simple Lisp interpreter in Rust
Well, the article is called "a simple Lisp", not "a fully featured Lisp". It's a demo, not a compliant implementation.

You may be interested by https://github.com/brundonsmith/rust_lisp though

linkdd··on Writing a simple Lisp interpreter in Rust
Author here, the article is more about how Rust and its ecosystem are nice tools for language designers rather than the beauty of Lisp.

The crates listed in that article are the ones I use for my compiler: https://letlang.dev

Lisp was only chosen as a way to demonstrate the power of those crates and Rust features. A kind of way of justifying my choices for Letlang.

It's not "you should do it like this" but "you can do it like this".

linkdd··on Ask HN: Faster than C, simpler than Python, safer than Rust. Possible?
Complementary video supporting my "fast is irrelevant" argument:

How slow is JavaScript really? Javascript vs C++ [Data Structures & Optimization] https://www.youtube.com/watch?v=WLwTlC1R2sY

linkdd··on Ask HN: Faster than C, simpler than Python, safer than Rust. Possible?
Done
linkdd··on Ask HN: Faster than C, simpler than Python, safer than Rust. Possible?
"Faster than C", I saw people write C code slower than a Python equivalent. So I have to admit, I don't know what it means for a language to be fast, because it depends on the algorithm being implemented and the developer who writes the code.

---

"simpler than Python", what does "simple" mean?

Simple design? Python's design is very complex (take a look at "Crimes with Python's pattern matching" < https://www.hillelwayne.com/post/python-abc/ > for example), on the other hand, assembly languages, or Lisp, or Forth, have a very simple design.

Simple as in "easy to use"? Rust is easy, write code, fix what the compiler tells you you did wrong. Joke aside, Go is quite easy to use and while I personally don't like this language, I get why it replaced Python in a lot of use cases.

Also, once you get used to the OTP framework, Erlang/Elixir/Gleam/any beam language are quite easy to use and have less footguns than Python.

---

"safer than Rust" is too vague. Is it memory safety? type safety? thread safety? cosmic ray safety? A mix of all of that?

Let's guess you meant "memory safety". All languages with a Garbage Collector are "memory safe".

---

On a semi-unrelated note, I've been working on https://letlang.dev

It's a language inspired by Erlang/Elixir (same concurrency model) that compiles to Rust code (the runtime use tokio). It is immutable, have no Garbage Collector thanks to Rust semantics, and dynamically typed.

I haven't run any benchmark (it's not even finished, I've been working on the specification before continuing the implementation), but I guess it could be slower than a rock.

---

For some recommendations, have you looked at Zig? Nim? Hare?

https://ziglang.org/ https://nim-lang.org/ https://harelang.org/

linkdd··on So what’s next (personal news from developer of popular CoreJS polyfill)
In the real world, there are no "good guys vs bad guys", no "white/black", it's all shades of grey, recognizing this is not "victim blaming".

But let's avoid flamewars irrelevant to the discussion.

linkdd··on So what’s next (personal news from developer of popular CoreJS polyfill)
> If a dev releases his work free-as-in-libre and/or free-as-in-beer, they don't get to complain if the donations are "insufficient".

Of course they get to complain. Complaining and doing nothing to change the situation is what's problematic.

Doing work without reward, even if you did not expect any in the first place, can be soul-sucking, and it is totally normal to complain about it.

You don't do FOSS for the recognition/glory, but complaining about the hatred, hypocrisy, and complete lack of respect of the industry towards FOSS is normal.

The backlash he got after he "dared" ask for help was completely uncalled for. I'd even say this, it's the user who does not get to complain, let's remind everyone of what most FOSS licenses include:

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  SOFTWARE.
You get a message during `npm install` from the dev asking for funding and a job? Tough shit, you don't get to complain because you're not paying him.
linkdd··on Ask HN: Do you use JSON Schema? Help us shape its future stability guarantees
This will be possible in my programming language https://letlang.dev It's going all in on dynamic typing.

NB: It's actually already possible, since the type system is already implemented, it's just that many features of the language are not yet available.

linkdd··on Erlang's not about lightweight processes and message passing
Not sure this is what GP is talking about but to implement the actor model in https://letlang.dev I use tokio.
← PreviousPage 6 of 29Next →