Gee, thanks #dialyzer, that's really, um, insightful ...
```
address_selector.ex:1:pattern_match
The pattern can never match the type.
Pattern:
false
Type:
true
_________________________________
done (warnings were emitted)
```
Gee, thanks #dialyzer, that's really, um, insightful ...
```
address_selector.ex:1:pattern_match
The pattern can never match the type.
Pattern:
false
Type:
true
_________________________________
done (warnings were emitted)
```
It's an absolute insanity to prototype code without types.
That includes #ElixirLang. Using #Dialyzer should be chapter 1 of any modern Elixir tutorial.
QT: https://social.doma.dev/@goo/109922182018482441
What we decided to do instead is to define two macros on the side. `defprod` is `defdata` that doesn't generate default constructors. It should be compatible with `defsum` out of the box, but we, for the time being, have the "no-new" counterpart called `defunion`.
Because unions are cool.
This way we don't break existing code, but allow easy to write smart constructors that don't upset #dialyzer.
The code is already live in the #GooLang #Algae fork: https://github.com/doma-engineering/algae-goo
Attention #Algae users. Functionality of generating `new` functions based on default values is staying, **but**, make sure to never write your own `new` functions yourself. Please write your constructors as `def mk`. If you used rose tree[1] implementation, you'll be hit with a breaking change as `rose.ex` moves to this convention. #Witchcraft #Elixir #Goo #MyElixirStatus #MyGooStatus https://en.wikipedia.org/wiki/Rose_tree
@ryansch we'll write a blog post after we publish a product using #Goo, but TL;DR is the following.
1. Why?
Despite #Witchcraft library being an established functional programming "prelude" for #Elixir (#AppSignal even has a blog post about it!) and #Elixir being a 1.x language, they still deprecate key features that make #Witchcraft ergonomic[1] and refuse to accept generalizations that would further improve FP programmers' user experience[2]. We don't want to comment on how we feel about it from the industrial language design best practices standpoint, but here's the pragmatic take. We have chosen #Elixir as the backbone of our stack over #Purerl because it has #Dialyzer and #Witchcraft, otherwise we would've contributed to #Purerl instead. So, practically, for us it's the path of least resistance to fork Elixir and reclaim the functionality we assumed it will have when we were choosing our stack.
# What?
There is no way to tell what #Goo will look like in the long run (think: post #Elixir v2). Practically, #Elixir upstream feature set can be characterised as "unpredictable".
In the immediate future, #Goo shall track #Elixir and maintain an FP-friendly patchset. In the immediate future, we also will be happy to accept more functional programming features both into the language *and* into the set of libraries we support[3].
The only thing we are certain about is that #Goo will forever be a super-set of #Elixir. So if Elixir v2 will diverge from Elixir v1 entirely, most likely we'll freeze Goo in favour of developing new projects in #purerl. Unless Goo will assemble a community, that is.
Not sure this train of thought answers your questions, feel free to follow-up.
[1]: https://elixirforum.com/t/how-difficult-would-it-be-to-add-the-infix-notation-a-la-haskell/19143/26
[2]: https://github.com/elixir-lang/elixir/pull/11588
[3]: https://social.doma.dev/@goo/109940130593807791
Is that really more clear/expressive than this? fn x -> x |> Binary.new!() |> then(& &1.raw) |> B.mk_url!() end or even fn x -> binary = Binary.new!(x) B.mk_url(binary.raw) end I guess it’s a matter of preference but the only thing valuable I see in your example is map as a more general(as in generic functor map) instead of just Enum.map. I get the value of a Functor and maybe even Monad or Monoid in your codebase if you enjoy these generalised operations in your codebase, but w...
What is "Success typing" and what does #Dialyzer have to do with it?
Reading through everything I can find, it does sounds like: "well I can't find all the errors, but the ones I do find - those exist".
Does Dialyzer only check for the `@spec` portions of #elixir code? So if I don't include that, my functions won't be checked?