Fl4m3Ph03n1x

Fl4m3Ph03n1x

Cannot understand warnings in Gradient

Background

I am now trying Gradual type checking, as a consequence I am giving a shot to Gradient. As I see it, this is an alternative to Dialyzer.

Problems

So, on my first ever code snippet, I started with a pure function:

defmodule TipCalculator do

  @spec getTipPercentage(List[String.t()]) :: non_neg_integer
  def getTipPercentage(names) do
    names_size = length(names)

    cond do
      names_size > 5 -> 20
      names_size > 0 -> 10
      true -> 0
    end
  end
end

From my point of view, my type checks are rather solid.
However, Gradient seems to have a different opinion:

===> Analyzing applications...
===> Compiling gradualizer
src/gradualizer.erl:45:2: Warning: opaque type top() is underspecified and therefore meaningless

src/typechecker.erl:3234:1: Warning: function type_check_cons_in/4 is unused
src/typechecker.erl:3247:1: Warning: function type_check_cons_union/4 is unused
src/typechecker.erl:4612:1: Warning: function verbose/3 is unused
src/typechecker.erl:4870:1: Warning: function gen_partition/3 is unused
src/typechecker.erl:4872:1: Warning: function paux/3 is unused

==> gradient
Compiling 14 files (.ex)
Generated gradient app
==> grokking_fp
Compiling 1 file (.ex)
warning: code block contains unused literal "\n" (remove the literal or assign it to _ to avoid warnings)
  lib/tip_calculator.ex: TipCalculator

Generated grokking_fp app
Typechecking files...
lib/tip_calculator.ex: Undefined remote type Access:get/2 on line 0

From what I can understand, this one piece of code (from a fresh project) has several issues:

  1. warning: code block contains unused literal “\n” (remove the literal or assign it to _ to avoid warnings)
  2. lib/tip_calculator.ex: Undefined remote type Access:get/2 on line 0

The fist one sounds like a warning credo (or a linter) would give me. So I am not really sure what do do with it. I am expecting a tool that does type checks only (maybe I am wrong?).

The second one, I have no idea.

Questions

What am I doing wrong?

Marked As Solved

Fl4m3Ph03n1x

Fl4m3Ph03n1x

Answer

I got confused a little bit, the correct typing was [String.t] and not List[String.t].

I will say however that:

lib/tip_calculator.ex: Undefined remote type Access:get/2 on line 0

Is not (to me) a very descriptive error message.
However, given the alternative (dialzyer) message is not much better:

lib/tip_calculator.ex:8:unknown_type
Unknown type: Access.get/2.

I will say however, the line number was an incredible help to find the issue.
With Gradient line 0 really threw me off.

Also Liked

OvermindDL1

OvermindDL1

The first thing about the warning looks like just a warning in the gradient’s source, not yours.

The second thing is because Access.get is how elixir desugars things like what looks like array accesses, so typing @spec getTipPercentage(List[String.t()]) :: non_neg_integer is actually typing @spec getTipPercentage(Access.get(List, String.t())) :: non_neg_integer, which doesn’t make much sense as a type. ^.^;

But yeah, that’s not an issue for erlang code, it’s just some of Elixir’s magic making the type error a bit weird.

Where Next?

Popular Backend topics Top

Rainer
Is there somewhere a good introduction to rust for experienced programmers (with years of C++/C#/Java experience)? Wanted to give it a t...
New
DevotionGeo
I know that -t flag is used along with -i flag for getting an interactive shell. But I cannot digest what the man page for docker run com...
New
Fl4m3Ph03n1x
Background I am trying to get a Github Action working with Windows and Bakeware because I am trying to create a release using it. Howeve...
New
JimmyCarterSon
Hello, I am working on a new application with Elixir, Dish_out. I want to see Data I follow this tutorial with Elixir Casts. However, I ...
New
MarkIden
Hi, Recommend pls your favorite learning resources in Go, with best books, podcasts etc.
/go
New
Fl4m3Ph03n1x
Background I am moving towards defined data structures in my application, and I find that TypedStruct is quite useful. Questions Howeve...
New
sona11
I’m having a difficulty. I want to modify an attribute’s data type from String to Array. { “id”: “trn:tarb:tradingpartner:uuid:00000...
New
Fl4m3Ph03n1x
Background I have a release file inside a tarball. However I want the final release to have some additional files and to move things aro...
New
Fl4m3Ph03n1x
Background I have an umbrella app where I use a dependecy called ETS. This dependency has a type called set_options that I use in some of...
New
pillaiindu
What is the difference between using :references and :belongs_to in the following command? bin/rails generate scaffold LineItem product:...
New

Other popular topics Top

AstonJ
Or looking forward to? :nerd_face:
503 14512 277
New
siddhant3030
I’m thinking of buying a monitor that I can rotate to use as a vertical monitor? Also, I want to know if someone is using it for program...
New
AstonJ
Curious to know which languages and frameworks you’re all thinking about learning next :upside_down_face: Perhaps if there’s enough peop...
New
AstonJ
Continuing the discussion from Thinking about learning Crystal, let’s discuss - I was wondering which languages don’t GC - maybe we can c...
New
AstonJ
We’ve talked about his book briefly here but it is quickly becoming obsolete - so he’s decided to create a series of 7 podcasts, the firs...
New
New
New
New
First poster: AstonJ
Jan | Rethink the Computer. Jan turns your computer into an AI machine by running LLMs locally on your computer. It’s a privacy-focus, l...
New
AstonJ
This is a very quick guide, you just need to: Download LM Studio: https://lmstudio.ai/ Click on search Type DeepSeek, then select the o...
New