Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EP002 - A new, better, more usable Prelude #4

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions proposals/EP002-NewPrelude.org
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#+TITLE: EP002 - A new, better, more usable Prelude
#+DATE:12/03/18

* Motivation
The Prelude is the biggest selling point of any programming language, it is the main interface
for the users. It is important to give good impression on the first contact with the newcomers
so we can acquire them as regular users.

Also, but not less important. Given that the Prelude is the main building block of any application,
it should be extremely readable, given that in the current world of software development it is
important that new members of any software project can start working in a project written in
Eta without too much hassle.

We should aim to avoid questions like "What does the L in foldl mean? foldList? foldLeft?" or
"What is the difference between map and fmap? Why should I avoid String?" .

We should not forget to include all the necessary abstractions from modules like ~Data.Functor~,
~Data.Monoid~ and so on.

* Teachability
The main way of teaching the Prelude would be in the official documentation and tutorials.

* Summary
We expect to add a module called ~Eta~ that should be imported in all source files within the
Eta language. We can do even better if we automatically import this module for all files with the
~*.eta~ extension.

* Design
** Aliases
*** Operators
- Pipe backwards ~<|~. Alias for ~$~.
- Pipe forward ~|>~. Alias for ~flip ($)~.
- Map backwards ~<$|~. Alias for ~<$>~.
- Map forward ~|$>~. Alias for ~flip (<$>)~.
- Apply backwards ~<*|~. Alias for ~<*>~.
- Apply forward ~|*>~. Alias for ~flip (<*>)~.
- Flatmap backwards ~<<|~. Alias for ~=<<~.
- Flatmap forward ~|>>~. Alias for ~>>=~.
- ~<+>~. Alias for ~<>~ in the ~Monoid~ class.
This might clash with ~<+>~ from ~Arrow~, but it might make sense to swap them,
as the mathematical symbol for monoids is much more similar to ~<+>~, and
for newcomers it implies concatenation automatically.

The main reason for these aliases is to allow writing code in a more natural way for newcomers.
For example:

#+BEGIN_SRC haskell
myFunction :: [Int] -> IO ()
myFunction someInputData
= someInputData
|> filter (>2)
|> map (+ 4)
|> monadicMap (\id -> readFile $ show id <> "_data.txt")
|$> length
|>> print
#+END_SRC

*** Functions
- ~identity~. Alias for ~id~.
We might be interested in removing support for ~id~ as it is a common
name in all domain models.
- ~first~. Alias for ~fst~ for tuples
- ~second~. Alias for ~snd~ for tuples
- ~constantly~. Alias for ~const~.
- ~successor~. Alias for ~succ~ in the ~Enum~ class.
- ~predecessor~. Alias for ~pred~ in the ~Enum~ class.
- ~map~ becomes an alias for ~fmap~. Dropping the list function
- ~mapFirst~. Alias for ~first~ in the ~Bifunctor~ class.
- ~mapSecond~. Alias for ~second~ in the ~Bifunctor~ class.
They should be redefined so they don't clash with the tuple functions.
- ~apply~. Alias for ~<*>~ from the ~Applicative~ class.
- ~flatMap~. Alias for ~=<<~ from the ~Monad~ class.
- Although ~return~ shouldn't be touched. We should advise to use ~pure~.
This would help newcomers to not get confused with the "regular" return
keyword in other languages.
- ~monoidIdentity~. Alias for ~mempty~ in the ~Monoid~ class.
- ~monoidAppend~. Alias for ~mappend~ in the ~Monoid~ class.
- ~monoidConcat~. Alias for ~mconcat~ in the ~Monoid~ class.
- ~isElementOf~. Alias for ~elem~.
- ~notElementOf~. Alias for ~notElem~.
- ~foldLeft~. Alias for ~foldl~.
- ~foldRight~. Alias for ~foldr~.
- ~strictFoldLeft~. Alias for ~foldl'~.
- ~strictFoldRight~. Alias for ~foldr'~.
The fold aliases imply the ones from the ~Foldable~ class.
- ~discard~. Alias for ~void~
- ~monadicMap~. Alias for ~mapM~
- ~discardMonadicMap~. Alias for ~mapM_~
- Probably many more there to improve readability.
** Additions
We should provide total alternatives to functions like ~head~, ~read~, etc...
These would be replaced with ~unsafeHead~, ~unsafeRead~, etc... denoting that they
are not recommended to use.

** A better numerical hierarchy
Add support for NumHask (https://github.com/tonyday567/numhask), so that users can benefit from a nicer
numerical hierarchy, specially for data science.

This prelude is 100% compatible with the current Haskell Prelude, and it makes no breaking changes, as it
just adds a nicer class hierarchy and QuickCheck properties.

* Unresolved
If we wanted to use "regular" Haskell functions, we might have some troubles with the new
aliases/additions. This could be fixed by importing some ~Eta.Legacy~ module.