Cool things you've seen in other languages/frameworks

I hacked around this morning making a very simple NIF generator (i learn by poking/prodding around).

You’re right, it becomes a nightmare very quickly. libm was perfectly lovely to generate something for, libzip turned into a disaster :sweat_smile:.

2 Likes

This is an ancient one but I remember being astounded by Smalltalk (30 years ago). The idea that the entire implementation of the language, the framework and your code were all co-existing and available for reflection was amazing for the time.

5 Likes

I miss ADTs, like I was used to have in Scala, where the compiler warns you if a case match is not exhaustive

4 Likes

I was about to post that I discovered true match exhaustion checking is available in Python, of all languages.

IMO, if it can be done in Python (via simple type hints and an external type checking tool) it can be done in Elixir some day. Not many Python people know about it, I think.

Here’s a crappy blog I wrote about it: Python + Pyright now do true match exhaustiveness checking – Dogweather

Here’s some sample Python code that’s clearer than my attempt to write it up. From GitHub - dogweather/python-exhaustiveness-adts-monads: Demo code showing off the new true exhaustiveness checks with Python 3.10 + Pyright - IMO this is pretty amazing:

@dataclass
class Ready:
    pass

@dataclass
class Scheduled:
    on: datetime.date


@dataclass
class Shipped:
    on: datetime.date
    with_carrier: Literal["UPS", "Fedex", "USPS", "DHL"]

OrderStatus_6 = Literal["unknown", "not available"] | Ready | Scheduled | Shipped


#
# Fails typecheck: Literals "unknown" and "not available" are not
# handled.
#
def handle_order_6a(status: OrderStatus_6):
    match (status):
        case Ready():
            print("The order is ready")

        case Scheduled(on) | Shipped(on, with_carrier=_):
            print(f"shipping date is {on}")


#
# Passes typecheck.
#
def handle_order_6b(status: OrderStatus_6):
    match (status):
        case Ready():
            print("The order is ready")

        case Scheduled(on) | Shipped(on, with_carrier=_):
            print(f"shipping date is {on}")

        case "unknown":
            print("The order status hasn't been entered into the system yet")

        case "not available":
            print("System error: unable to access the order status")
1 Like

oh this was one of my (other) favorite features of Elm (other than the time-travelling debugger mentioned previously)

2 Likes

Dialyzer can already do this, although it’s exhausting to work with in it self :joy:

2 Likes

You might be interested in this talk on DX which was posted yesterday.

2 Likes

one thing comes to mind is an actor-model-native but natively (llvm) compiled language, Pony. It’s not based on “share (almost) nothing” but follows a different path: object capabilities with the syntax mainly being rather lean if one does the safe default thing.

Ash can do this at a basic level, and could eventually be expanded to work on streams for example. It just hasn’t come up as a use case for me/others yet.

Ash isn’t tied to SQL, and have an ETS and Mnesia data layer which are unoptimized at the moment and just work on top of enumerables.

You could do something like this today though:

defmodule Something do
  use Ash.Resource

  attributes do
    attribute :name, :string, default: "foo"
  end
end

records = [
  %Something{name: "foo"}, 
  %Something{name: "bar"}, 
  %Something{name: "baz"}
]

require Ash.Query

Something
|> Ash.Query.sort(name: :asc)
|> Ash.Query.filter(name in ["bar", "baz"])
|> Ash.Query.apply_to(records)
# => [%Something{name: "bar"}, %Something{name: "baz"}]
1 Like

Not to give you homework, but I believe FoundationDB has the multi-paradigm use-cases that can be used to inform a more universal yet not SQL-centered DSL for persistence.

I know it’s a monumental task. Just giving you a potential attack vector, should you want to tackle this one day.

I was just referring to applying a query to a potentially infinite stream as not a use case that has come up. We’ve got a data layer pattern that works across many sources.

Ash has data layers for: postgres, sqlite, ets, mnesia, csv files, cubdb, neo4j, in-memory data (i.e just lists of structs), sanity CMS, and unreleased data layers for: mysql, markdown files, external APIs, and more from the community.

4 Likes

I want to mention that this is doable within Elixir if you have an event-sourcing or redux style programming model.

For some subsystems in our application, the state is computed from an event log. I have an internal tool where i can drag a slider to view the state of an entity at a point in time.