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

I'm not a C++ programmer, but I was under the impression that closures in c++ were just classes that overload the function call operator `operator()`. So each closure could also be implemented as a named class. Something like:

    class OnListItemSelected {
        OnListItemSelectedData data;

        void operator()(int selectedIndex) { ... }
    }
Perhaps I'm mistaken in what the author is trying to accomplish though?


Indeed, that is exactly the case, lambdas are essentially syntax sugar for doing this.

The one thing the author's solution does which this solution (and lambdas) does not is type erasure: if you want to pass that closure around, you have to use templates, and you can't store different lambdas in the same data structure even if they have the same signature.

You could solve that in your case by making `void operator()` virtual and inheriting (though that means you have to heap-allocate all your lambdas), or use `std::function<>`, which is a generic solution to this problem (which may or may not allocate, if the lambda is small enough, it's usually optimized to be stored inline).

I get where the author is coming from, but this seems very much like an inferior solution to just using `std::function<>`.


The author of the article freely admits that `std::function<>` is more flexible. He still prefers this solution, as it is easier for him to reason about. This is covered in the "Fringe Benefits" part of the document.


> though that means you have to heap-allocate all your lambdas

I think whether or not you have to allocate from the heap depends on the lifetime of the lambda. Virtual methods also work just fine on stack-allocated objects.


Fair point, but generally speaking, callbacks tend to escape the scopes they are in (if you have a callback for ”user clicked mouse”, it’s likely not going to be triggered in your current scope), so stack-allocation isn’t really an option.

But yes, fair point: they can be stack or statically allocated as well.


Exactly! And if you need type erasure, you can just store it in a std::function.

> OnListItemSelectedData data;

In this case you can just store the data as member variables. No need for defining an extra class just for the data.

As I've written elsewhere, you can also just use a lambda and forward the captures and arguments to a (member) function. Or if you're old-school, use std::bind.


Main issue author had with lambdas is autogenerated names in crash reports


Yes, but that's exactly why I mention this. By explicitly creating a class (that behaves the same as a lambda) the author might get better names in crash reports.


> - when having non trivial ecosystem one cannot selectively deprecate and get errors, this has to be a human process (remember to replace…)

Apart from some statically typed languages (and even then), most languages have this. Very rarely in any ecosystem does a dependency upgrade not also require manual changing of stuff.

> - when doing umbrella tests on non compiled code seed influences order of compilation > - this order of compilation influences outcome and can lead to buggy code

I've never seen compilation produce odd artifacts, especially not as a result of compilation order. If the code has the proper compile-time deps, then the result seems stable.

> - documentation is hard to use - searching shows random versions and there isn’t even a link to „open newest”

Isn't this the fault of the search engine not having the latest version indexed? There's also a version selector on the top-left of hexdocs. Navigating to hexdocs.pm/<LIBRARY_NAME> also opens the latest version. This seems like a non-issue to me.

> - a lot of knowledge is implicit (try checking if you can dynamically add children to a Supervisor)

Already covered by another commenter, but also: https://hexdocs.pm/elixir/DynamicSupervisor.html I don't think the knowledge is necessarily implicit, it's just that learning Elixir deeply also means learning the BEAM/Erlang deeply, and there's a lot of Erlang docs.

> - sidebar with new ExDocs break for some reason so there is no navigation

Not a universal problem. Perhaps look into why it's broken on your device and report it as a bug?

> - there is no way to browse navigation outside this broken ExDocs which outputs only HTML and LSP

There's iex. For example `h String.codepoint`. Aside from that, I sometimes just open the relevant library in my deps/ directory and search there.

> - Squiggly arrow works weird (i.e. ~0.3 might catch 0.99)

I genuinely don't understand what you mean by this. There's no tilde operator and ~0.3 is invalid syntax. Can you give a code sample?

> - dependency compilation is not parallelized

I think this might be related to the common pattern of code you see in libraries:

    if Code.ensure_loaded?(SomeModuleFromAnotherLib) do
       # Some lib is loaded, add code to integrate with it.
    end
I think that could only be solved if that integration were extracted into another lib with properly setup deps, but due to how common this pattern is I don't think it's ever possible to switch to parallel dep compilation.

> - Dialyzer/dialyxyr typespecs are useless most of the time

A type system is being worked on, and each release lately has added more checks.

I agree that compilation is slow & editor integration is meh, but the rest I don't agree with.


I've also been thinking entirely too much about a good recipe structure.

For now I've ended up on ingredients being more or less recipes themselves, and recipes being recursive (as in, recipes use other recipes to create new recipes). Some recipes you can either buy & make yourself. For example, sweet soy sauce: easy enough to make but you could also just buy it in the store. The resulting structure is basically:

  Recipe:
    directions: rich text
    storageInstructions: rich text
    prepTime: minutes
    cookTime: minutes
    priceEstimateperServing: money
    ingredients: RecipeIngredient[]
    // other fields (e.g. tags, id, name, slug, purchaseableAt, nutrients, etc)

  RecipeIngredient:
    recipeId: reference to recipe
    ingredientId: reference to recipe as well
    // Allows grouping ingredients (e.g. "sauce", although the sauce could be a recipe of its own instead)
    group: string | null
There's some challenges with this though:

- If you have a shopping list, how do you determine in a complex recipe which "recipes" you'll purchase and which you'll make from scratch (UX issue)

- Some recipes may have alternatives instead (for example: if allergic to X, substitute with Y)

- It puts a lot of burden on the recipe writer.

- Some recipes don't scale linearly with just the ingredients, but perhaps also the cookware (baking a cake for example). Cooklang docs talk about this as well.

Scaling of recipes could be done with a measurement-aware type. Something similar to frinklang[0] for example.

[0]: https://frinklang.org/


While the UI is not my favorite, I can see a history of my songs played. On android, click on home, click your avatar (top left). A menu should slide out with "Listening history" in it.


Oh my gosh... well... thanks for that. I've been wanting that feature for many years.

That is bizarre UI/UX. I should just be able to scroll up when viewing my play queue or have a button directly on that page to see the history.


Gleam?


You can skip the last Enum.map/into and just use Map.new:

    "file.json"
    |> File.read!()
    |> Jason.decode!()
    |> Stream.flat_map(& &1["children"])
    |> Map.new(fn child -> {child["id"], child} end)


> the 'with' construct allows a list of conditional patterns and then a general 'do' block, whereas the Erlang 'maybe' allows mixed types of expressions that can either be conditional patterns or any normal expression weaved in together at the top level.

This seems slightly incorrect to me. You can write expressions in Elixir's with macro too, by simply swapping the arrow for an equals sign. For example, this is perfectly valid Elixir code:

    with {:ok, x} <- {:ok, "Example"},
         IO.puts(x),
         len = String.length(x) do
      IO.puts(len)
    end
Did you mean something else?


See https://news.ycombinator.com/item?id=31425298 for a response, since this is a duplicate. TL:DR; I had never seen it and had no idea it was possible because I don't recall seeing any documentation or post ever mentioning it! Ignorance on my part.


There seems to be a slight encoding issue with external URLs. In the dependencies section under "Private Hex Mirrors", there is a link to mini_repo which results in a 404. It seems like the underscore in mini_repo is encoded to %5f which github doesn't seem to like?


If I'm not mistaken qutebrowser also has this feature.


Yup! It has various kinds of shortcuts for this kind of thing (increment/decrement number, find prev/next link, remove component from path).

If you're curious, the implementation is here: https://github.com/qutebrowser/qutebrowser/blob/master/quteb...


It is a common feature in vimperator-like browsers.


Here's a good short description with further resources for reading:

https://github.com/springernature/frontend-playbook/blob/mas...


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

Search: