Skip to content

Feedback on qualified names #152

Description

@maxigit

I understand this package has been intended to be imported qualified. But some people (like me) don't like qualified import neither they do like to be forced to do so (when there is no real need to do so)

Moreover, the tutorial import DataFrame as D and DataFrame.Functions as F? Why using to different letters ? (Haskell syntax allows to import different modules with the same qualifier)
Is it for clarity or because using the same name for both will result in name conflict ?
I find it rather confusing (and unnecessary) to have remember what is in F or in D.
Could not DataFrame not export everything ?

I probably could try importing DataFrame.Functions without qualifying it , because things like name and col makes perfect sense on their own, but then things like div and lift conflicts with the prelude.
Could not Expr a be made an instance of Integral and/or Applicative/Monad ?

Activity

  1. mchav commented on Feb 19, 2026

    @mchav
    Member

    Why qualified imports

    I guess I never knew they were a problem cause all the tools I use assume they are e.g. import pandas as pd and import polars as pl, import qualified Data.Text as T and so forth for Haskell maps, sets and other things that are expected to clash a lot with Prelude. But now that you point it out I see why they are annoying. I'm curious how you use packages like containers/text without all the namespace clashes?

    Why the functions namespace

    The expression stuff came a little later and at the time I was writing a lot of pyspark at work. PySpark puts all the columns looking functions in a functions namespace. Aside from that a lot of the initial functions clashed with other functions in the uber namespace.

    E.g.

    D.mean col df -- get mean of a column as a value.
    D.derive "m" (F.mean col) df -- mean expression

    Monad/applicative/integral instances

    toInteger is undefined for expressions unless you have an accompanying dataframe. So are toRational and toEnum which integral requires. I guess we could make those specific functions throw exceptions but fully define all the other functions in the class so they don't use them but then you get surprising behaviour from time to time when you assume toInteger works.

    Monad instances require the type to be unconstrained. We at least need a show constraint so probably not possible. Also some laws would just not hold for expressions. It gets messy. But this is something I've fought with GHC about for months. Open to solutions.

  2. maxigit commented on Feb 19, 2026

    @maxigit
    Author

    I'm curious how you use packages like containers/text without all the namespace clashes?

    I rarely need everything from everything in one file, so I usually manage to import the main one unqualified and hide/expose/qualify the extra one. But I'll reuse the same name for the same package if possible as in

    import Text.Megaparsec qualified as P
    import Text.Megaparsec.Char qualified as P
    import Text.Megaparsec.Char.Lexer qualified as P hiding (space)
    

    I don't like Haskell qualified syntax because it makes things look like constructor or type. Python panda.read_csv is consistent with OO python syntax. F.col looks like F_col.

    Aside from that a lot of the initial functions clashed with other functions in the uber namespace.

    Well, it is an egg and chicken situation. If you qualify, you can have duplicate and once you have duplicates you'll need to qualify :-)

    toInteger is undefined for expressions unless you have an accompanying dataframe

    Fair enough, I didn't think of toInteger. I'm not sure why it is even need to integer division. It is probably due to the original Num hierarchy. It is just odd that you can use / and * from the Prelude, but not mod and div ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions