Hacker Newsnew | past | comments | ask | show | jobs | submit | more plainOldText's commentslogin

From the article:

> In summary:

> Use “your” when communicating to the user

> Use “my” when the user is communicating to us

I could see how this makes sense with dialogs.

But for UI elements? Should I name say a tab “My Pictures” and not “Your Pictures” because clicking on said tab I’m communicating to the system I want to see my pictures?


No, you should name it "Your Pictures" because the app is communicating to the user that in this tab there are "your pictures". The article gives an example for the case:

> Similarly, a support agent might tell you to “Go to your cases” over webchat or a phone call. This is confusing if the UI says “My cases”.

Replace "cases" with "pictures" :)

If, however, there's a button which lets you upload pictures, it should be "Upload my picture", because the user is the one who's communicating to the app about their intent.


Hmm, I guess this then makes sense if we regard the app as a latent space projecting user's data, so its views are awaiting to be activated.

Seen this way, the app is basically communicating to the user: Hey I have "Your Pictures", "Your Cases", etc. Click to find out.

But to me the "My ..." variation also makes sense. e.g. In Photos app on macOS you will see "My Albums", "My Projects", and although they can be renamed, I don't think I created them.


I couldn’t see passed the 100% mark.

Looking at some YouTube videos, it looks like this was the greeting upon booting:

“Stored on this single, 1.44 Mbyte floppy disk is a demo copy of the QNX realtime operating system, the Photon microGUI windowing system, the Voyager web browser, Ethernet networking, TCP/IP, an embedded web server, an editor, a file browser, a vector graphics animation, and a television set-top box simulation.

Just think — if we can do all this with a 1.44 Mbyte floppy disk, imagine the devices you could build with QNX realtime technology.”


Some core ideas from the paper for the inpatient (failures, isolation, healing):

- Failures are inevitabe, so systems must be designed to EXPECT and recover from them, NOT AVOID them completely.

- Let it crash philosophy allows components to FAIL and RECOVER quickly using supervision trees.

- Processes should be ISOLATED and communicate via MESSAGE PASSING, which prevents cascading failures.

- Supervision trees monitor other processes and RESTART them when they fail, creating a self-healing architecture.


Yeah, CamelCase for modules, snake_case for functions and variables.

Your brain can instantly tell what entity you’re dealing with.


We used to infer one’s mind from their writing. Nowadays?

I’m surprised people are too lazy to even remove them dashes. Well, in fact it might actually be a good thing for one can spot when something was AI generated much easier.

I feel like original writing is pretty much dead these days. We’re all best selling authors now.


I've been (over) using em-dashes ever since I discovered them. I have no intention of changing.

Curiously, I find in editing my dad's auto-biography that a certain generation went crazy over-inserting commas — wherever they think you might want to pause to take a breath or something. To my eye (ear?) the result is a staccato sentence.

But the truth is I know nothing about grammar rules — I slept through sentence diagramming in elementary school.


This reads like original writing to me. Too creative for LLMs, at least based on my experience.


I used em-dashes before ChatGPT became a thing, I will keep using them.


Judging from the small example in the readme, the language looks pleasing to the eye.

What’s under the hood though? What are some of the technical choices, performance characteristics and longer term goals?


The current implementation looks like a compiler to a stack-based bytecode with a straightforward textbook interpreter. For example, here is the interpretation of the Add bytecode: https://github.com/egranata/aria/blob/master/vm-lib/src/vm.r...

So to a very rough first approximation, performance characteristics should be in CPython's ballpark.


I just noticed this comment a few days late, so sorry for the delay in answering

Goals are documented in a roadmap doc: https://egranata.github.io/aria/ROADMAP.html as well as issues on GitHub, and ideas are always very welcome, so please bring yours! I'd love to chat

I am not (yet) focused on performance, it's still at a point where the language and the library are changing. It runs decently well (as mentioned it's a stack based VM) such that you could actually use it to write some real programs. Good enough for a 0.9 I think

Technical choices, I have a few big ideas that stand behind the overall design: - easy to pick up, flexible, run with, write code, "pleasing to the eye" is what you called, that's #1; - a simple module system that works with you (with more improvements in the roadmap); - easier to reason about errors (lots of things are Maybe/Result-style enums vs. exceptions) - this is somewhat inspired by Midori where errors are classified according to whether you can and should handle them (with exceptions as a somewhat middle ground); - using Rust under the hood provides stronger memory safety guarantees than things written in C/C++ would out of the box (I have seen the occasional stack overflow error, and even that I would consider a bug, but no segfault core dump using Aria); - no inheritance, prefer composition, reuse via mixins which are first class in Aria - I found this works quite nicely (for example, I can provide all comparison operators based on one function + a mixin: https://github.com/egranata/aria/blob/master/lib/aria/orderi...)

Thanks for all the questions!


This video https://youtu.be/TBrPyy48vFI?t=1277 is a few years old, but it covers how the GRiSP platform combines Erlang and RTEMS Real-time OS [1] to overcome Erlang VM's soft real-time limitations and achieve hard real-time event handling.

[1] https://www.rtems.org/


What are the soft real time limitations of erlang?


Erlang's BEAM, assuming no chicanery of NIFs, will use reduction counting to eventually yield a scheduler to make sure other Erlang processes get execution time. This gives you kind of a "will eventually happen" property. It can't guarantee meeting a deadline. Just that all things will be serviced at some point.


Right GRiSP has support for creating RTOS tasks in C, IIRC.

Within BEAM itself there’s no priority mechanism, however, on a RPi3 or BeagleBone you could get about an 200 uS average response time to GPIO on Linux, even under moderate load. The jitter was pretty low too, like 10-20 uS on average, but the 99.9% tail latencies could get up to hundreds of millis.

That’s fine for many use cases. Still I now prefer programming on esp32’s with Nim for anything realtime. Imperative programming just makes handling arrays easier. Just wish FreeRTOS tasks had error handling akin to OTP supervisors.

Now Beam/Elixir would be amazing for something like HomeAssistant or large networked control systems.


Erlang does have a mechanism to modify process priority, with process_flag/2,3.

As of OTP 28 there's also priority messaging that a process can opt in to. Not really related, but it's new and interesting to note.


> As of OTP 28 there's also priority messaging that a process can opt in to.

That's a very important feature. Without priority messaging you can't nicely recover from queues that start backing up.


Just a reminder that commonly "real-time" on stuff like VxWorks isn't hard realtime either. You test a bunch of scenarios, put in some execution CPU head-room you are comfortable with, and call it a day. With enough head-room and some more (or less, if you have money and time) hand-waving, you can more or less guarantee that deadlines will be kept.


It's all relative. Hard Realtime vs Soft Realtime is not clearly delineated. Because on anything real world there is always a probability distribution for every deadline.

Our observation is that Erlang's "soft-realtime" is already getting much harder once Linux stays out of the way. We have a master thesis worth of research on having multiple sets of schedulers in one Erlang VM that run on different hard real-time priorities plus research on a network of message passing and garbage collecting Erlang processes can be doing Earlies Deadline First scheduling.

However that stayed prototypical because we found relativeness of vanilla Erlang on RTEMS was good enough for all practical customer problems we solved.

For very high performance hard real-time we drop down to C and we are currently working on a little language that can be programmed from the Erlang level that avoids that.


quick-question: why go the `rtems` route ? would 'isolcpus' not work in this case ?

--

thanks !


With Linux we can only run on larger embedded CPUs that support virtual memory well enough. With RTEMS we can go towards much smaller platforms.


Addendum: we have Buildroot and Yocto based platforms too. Not clear on the website right now but we have three platforms actually:

* GRiSP Metal - aka just GRiSP (Erlang/Elxiir + RTEMS)

* GRiSP Alloy - Buildroot Linux based, starts the Erlang/Elixir runtime as process 1 similar to Nerves but more language agnostic (Nerves is for Elixir only) and we support RT Linux and running multiple Erlang Runtimes at different priorities

* GRiSP Forge - Similar to alloy but Yocto based.

The idea is that from the high level language level they are more or less interchangeable.


ah ! indeed it can. do such platforms have 18m of memory and then some ?


I am not associated with the project, so I cannot answer that.


Heads up, the links to Paul Butcher's datalog posts are broken. The series can be found here now: https://paulbutcher.com/datalog1.html


Thanks-- I fixed the links!


I think their DIDYOUKNOW.md file in the source code is worth showing in full, as it describes the language in a more compact form:

---

# Did You Know?

## Language

Did you know that:

- Flix offers a unique combination of features, including: algebraic data types and pattern matching, extensible records, type classes, higher-kinded types, polymorphic effects, and first-class Datalog constraints.

- Flix has no global state. Any state must be passed around explicitly.

- Flix is one language. There are no pragmas or compiler flags to enable or disable features.

- Flix supports type parameter elision. That is, polymorphic functions can be written without explicitly introducing their type parameters. For example, `def map(f: a -> b, l: List[a]): List[b]`.

- the Flix type and effect system can enforce that a function argument is pure.

- Flix supports effect polymorphism. For example, the `List.map` function is effect polymorphic: its purity depends on the purity of its function argument.

- in Flix every declaration is private by default.

- In Flix no execution happens before `main`. There is no global state nor any static field initializers.

- Flix supports full tail call elimination, i.e. tail calls do not grow the stack. Flix -- being on the JVM -- emulates tail calls until Project Loom arrives.

- Flix supports extensible records with row polymorphism.

- Flix supports string interpolation by default, e.g. "Hello ${name}". String interpolation uses the `ToString` type class.

- Flix supports the "pipeline" operator `|>` and the Flix standard library is designed around it.

- In Flix type variables are lowercase and types are uppercase.

- In Flix local variables and functions are lowercase whereas enum constructors are uppercase.

- Flix supports set and map literals `Set#{1, 2, 3}` and `Map#{1 => 2, 3 => 4}`.

- Flix supports monadic do-notation with the `let*` construct.

- Flix supports "program holes" written as either `???` or as `?name`.

- Flix supports infix function applications via backticks.

- Flix compiles to JVM bytecode and runs on the Java Virtual Machine.

- Flix supports channel and process-based concurrency, including the powerful `select` expression.

- Flix supports first-class Datalog constraints, i.e. Datalog program fragments are values that can be passed to and returned from functions, etc.

- Flix supports compile-time checked stratified negation.

- Flix supports partial application, i.e. a function can be called with fewer arguments that its declared formal parameters.

- the Flix type and effect system is powered by Hindley-Milner. The same core type system that is used by OCaml, Standard ML, and Haskell.

- the Flix type and effect system is sound, i.e. if a program type checks then a type error cannot occur at run-time. If an expression is pure then it cannot have a side-effect.

- the Flix type and effect system supports complete type inference, i.e. if a program is typeable then the type inference with find the typing.

- The Flix "Tips and Tricks"-section https://doc.flix.dev/tipstricks/ describes many useful smaller features of the language.

- Flix has a unique meta-programming feature that allows a higher-order functions to inspect the purity of its function argument(s).

- Flix names its floats and integers types after their sizes, e.g. `Float32`, `Float64`, `Int32` and `Int64`.

- Flix -- by design -- uses records for labelled arguments. Records are a natural part of the type system and works for top-level, local, and first-class functions.

- Flix -- by design -- has no implicit coercions, but provide several functions for explicit coercions.

- Flix -- by design -- disallows unused variables and shadowed variables since these are a frequent source of bugs.

- Flix -- by design -- disallows allow unused declarations. This prevents bit rot.

- Flix -- by design -- does not support unprincipled overloading. Instead, functions are given meaningful names, e.g. `Map.insert` and `Map.insertWithKey`.

- Flix -- by design -- does not support variadic functions. We believe it is better to pass an explicit array or list.

- Controversial: Flix defines division by zero to equal zero.

- Controversial: Flix defines String division as concatenation with the path separator. For example, `"Foo" / "Bar.txt" => "Foo\Bar.txt"` on Windows.

## Standard Library

Did you know that:

- Flix has an extensive standard library with more than 2,600 functions spanning more than 30,000 lines of code.

- the Flix Prelude, i.e. the functions which are imported by default, is kept minimal and contains less than 20 functions.

- most higher-order functions in the Flix standard library are effect polymorphic, i.e. they can be called with pure or impure functions.

- the Flix type and effect system enforces that equality and ordering functions must be pure.

- the Flix standard library uses records to avoid confusion when a function takes multiple arguments of the same type. For example, `String.contains` must be called as `String.contains(substr = "foo", "bar")`.

- the Flix `List` module offers more than 95 functions.

- the Flix `String` module offers more than 95 functions.

- the Flix `Foldable` module offers more than 30 functions.

- the Flix standard library follows the convention of "subject-last" to enable pipelining (`|>`).

## Ecosystem

Did you know that:

- Flix has an official Visual Studio Code extension.

- Flix has an official dark theme inspired by Monokai called "Flixify Dark".

- the Flix website (https://flix.dev/) lists the design principles behind Flix.

- Flix has an online playground available at https://play.flix.dev/

- Flix has online API documentation available at https://doc.flix.dev/

- the Flix VSCode extension uses the real Flix compiler.

- the Flix VSCode extension supports auto-complete, jump to definition, hover to show the type and effect of an expression, find all usages, and more.

- the Flix VSCode extension has built-in snippets for type class instances. Try `instance Eq [auto complete]`.

- the Flix VSCode extension supports semantic highlighting.

- the Flix VSCode extension has built-in "code hints" that suggests when lazy and/or parallel evaluation is enabled or inhibited by impurity.

- Flix has community build where Flix libraries can be included in the CI pipeline used to build the Flix compiler.

- Flix has a nascent build system and package manager based on GitHub releases. Today it is possible to build, package, and install Flix packages. Dependency management is in the works.

## Compiler

Did you know that:

- Flix -- by design -- has no compiler warnings, only compiler errors. Warnings can be ignored, but errors cannot be.

- the Flix compiler uses monomorphization hence primitive values are (almost) never boxed.

- the Flix compiler supports incremental and parallel compilation.

- the Flix compiler has more than 28 compiler phases.

- the Flix compiler contains more than 80,000 lines of code.

- the Flix compiler has more than 13,500 manually written unit tests.

- the performance of the Flix compiler is tracked at https://arewefast.flix.dev/

## Other

Did you know that:

- Flix is developed by programming language researchers at Aarhus University (Denmark) in collaboration with researchers at the University of Waterloo (Canada), and at Eberhard Karls University of Tübingen (Germany), and by a growing open source community.

- Several novel aspects of the Flix programming language has been described in the research literature, including its type and effect system and support for first-class Datalog constraints.

- Flix is funded by the Independent Research Fund Denmark, Amazon Research, DIREC, the Stibo Foundation, and the Concordium Foundation.

- more than 50 people have contributed to the Flix compiler.

- more than 2,000 pull requests have been merged into the Flix compiler.


"Controversial: Flix defines division by zero to equal zero." Wait what. Can I read up on the motivation somewhere?


The FAQ (https://flix.dev/faq/#:~:text=Dividing%20by%20zero%20yields%...) links to https://www.hillelwayne.com/post/divide-by-zero/, which is more about Pony, but links to https://xenaproject.wordpress.com/2020/07/05/division-by-zer... which properly explains that it's helpful for proof assistants to define division by zero, with particular reference to Lean. Really it's defining a division-like function (Lean calls it real.div) that disagrees with division in this one way, and then making "/" use it. It's unclear to me if this is sensible in a general purpose programming language that isn't a proof assistant.


Ah thanks for the insights and references. And yes I'm still curious why this definition of div/0==0 is needed in the context of Flix


Gotta be honest, this isn't very inspiring : "Wait, division by zero is zero, really? Yes. But focusing on this is a bit like focusing on the color of the seats in a spacecraft."


This language seems to be aiming high. Congrats!

Looking at their code however, I'm realizing one thing Elixir got "right", in my view, is the order of arguments in function calls.

For example, in Elixir to retrieve the value associated with a key in a map, you would write Map.get(map, key) or Map.get(map, key, default).

This feels so natural, particularly when you chain the operations using the pipe operator (|>):

  map
  |> Map.put(key, value)
  |> Map.get(key)
In Flix it seems one needs to write Map.get(x, map), Map.insert(x, y, map). I guess it follows in the footsteps of F#.


But in Flix you can write:

  def main(): Unit \ IO = 
      Map.empty() |>
      Map.insert("Hello", "World") |>
      Map.get("Hello") |>
      println
So I am not sure what you mean? In general, if you like pipelines then you want the "subject" (here the map) to be the last argument. That is how it is in Flix.


Sorry, I wasn't clear. Yes, you can have pipelines in Flix, F#, OCaml, to me however placing the "subject" first feels more natural, as function signatures (not necessarily in pipelines) have a symmetry not encountered otherwise:

Subject First:

  Map.put(map, key, value)
  Map.get(map, key)
  Map.get(map, key, default)
  Map.del(map, key)
Subject Last:

  Map.put(key, value, map)
  Map.get(key, map)
  Map.get(key, default, map)
  Map.del(key, map)


Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: