What is a qualified import?

OK, I’m going through this post line by line.

What is the need for import qualified for DA.List here?

Are there other modules with the same name, is that the reason?

I checked a couple of reference docs in the documentation both for File structure and Packages

It seems to suggest that some modules can have the same name so that’s why sometimes you need to do a qualified import?

Do I understand this correctly?

Excellent questions, moved to a separate topic so it’s easier for others to find if they have the same question.

Also to answer your question a qualified import makes it so that all functions in DA.List need to be referred to as DA.List.functionName rather than functionName. This is to avoid naming conflicts where two modules have a function with the same name because if you called functionName and it was in two different modules the compiler wouldn’t know which one you were referring to.

1 Like

Hi @krmmalik,

What is the need for import qualified for DA.List here?

When you start a new Daml file, by default you have access to all of the functions defined in a “special” module called Prelude. It’s only special in that it is automatically imported in all Daml files.

Daml comes with many other modules, however, but these have to be manually imported. There are multiple ways to do that. Schematically, assuming you have a file Module.daml with content like:

module Module where

one = 1
two = 2

Obviously not a very useful one, but it will serve its purpose. Here are a few examples of how import statements work:

import Module

test = script do
  assert $ one == 1
  assert $ two == 2
  assert $ Module.one == 1
  assert $ Module.two == 2
import Module as M

test = script do
  assert $ one == 1
  assert $ two == 2
  assert $ M.one == 1
  assert $ M.two == 2
import qualified Module as M

test = script do
  assert $ M.one == 1
  assert $ M.two == 2
import qualified Module

test = script do
  assert $ Module.one == 1
  assert $ Module.two == 2
import qualified Module (one)

test = script do
  assert $ Module.one == 1
import Module (one)

test = script do
  assert $ one == 1
  assert $ Module.one == 1

So you have a few options:

  • A naked import Module lets you access all the names in Module either directly as name or “qualified” as Module.name.
  • Adding an as to the import statement changes the prefix used when qualifying an imported name.
  • Adding the qualified keyword restricts the imported name to only their qualified form.
  • Adding a list of names to the import statement restricts the import to just those names.

Now imagine Module.daml has:

module Module where

map = "map"

and you want to write:

import Module

test = script do
  assert $ map == "map" -- compilation error

This is the case described by @anthony: the compiler doesn’t know which map you’re referring to (there is one in Module, but there is also one in Prelude).

You can still qualify the names if you want:

import Module

test = script do
  assert $ Module.map == "map"
  assert $ Prelude.map (*2) [1, 3, 7] == [2, 6, 14]

So, bottom line:

  • There is no error if you have multiple imports that add the same name to the local list of available names.
  • There is an error if you try to use an unqualified version of a name that has been imported multiple times.
  • You can always qualify names at the point of use.

So using a qualified import is not necessary to resolve the ambiguity: you could choose to only qualify the names that do have a conflict.

I simply prefer, as a matter of personal taste, to always qualify all of my imports. I think that makes the code easier to read because, when I look at some of my code, I immediately know where a name comes from. Other people think that makes the code harder to read because all the names have long prefixes. There isn’t really a “right” answer here (except, you know, mine), it really is a matter of personal preference.

7 Likes

Thanks for your answer. I am continually impressed with how much thought has gone into DAML.
As a non-coder but someone that has always wanted to be able to create something meaningful via code I’ve tried a number of languages and environments and ended up giving up quickly despite the community being quite large.

DAML is the first platform I have come across, where even though I am finding each day a struggle (due to my weakness in coding) I am continually inspired to continue because of what DAML makes possible.

I hope I’m still able to utter these same words in the next few months but this is how I feel about it right now.

The documentation leaves a fair bit to be desired for non-coders however, but that’s also understandable because your key demographic is probably still coders.

2 Likes

Absolutely wonderful explanation. I’m very grateful for all the time you’re taking each day to break down each point for me and really help me understand what is going on. My greatest challenge in trying to create something meaningful in any coding environment is learning to become intimately familiar with the syntax so this helps me a huge deal.

I can totally understand too, why you would qualify imports as well. When you did that, it definitely made the code easier for me to read as well.

3 Likes

I wrote a short blog post explaining qualified imports here:

1 Like