Maybe vs Option vs Optional vs ?

1,160 views
Skip to first unread message

Evan Czaplicki

unread,
Feb 3, 2013, 5:15:23 AM2/3/13
to elm-d...@googlegroups.com
Warning, these are rough ideas and small details that I just want to discuss!

One of the few things that bugged me about the basic facts of Haskell was the name Maybe. Coming from ML, I thought it was a sort of goofy choice that added character but decreased clarity.

I am thinking that it will be fairly common to have large records with many optional fields. Grzegorz already used this pattern in Preselm, and I think it is generally useful for simulating optional arguments to a function. In this case, I think the name Maybe is at its worst.

type Frame = { color :: Optional Color, content :: Optional Element }
type Frame = { color :: Option Color, content :: Option Element }
type Frame = { color :: Maybe Color, content :: Maybe Element }

I remember learning and teaching ML and wondering why they left off the "al". I think two or three characters is a small price to pay for such an increase in clarity/intuitiveness. Then again, maybe it is important to distinguish between modelling optional values and something actually being optional (i.e. optional arguments are a thing so people may assume they can just leave it off).

I also kind of prefer (Some a | None) over (Just a | Nothing). I like that some and none are the same length. I also think both are kind of weird. Maybe (Yes a | No)? Any other ideas?

Between Elm's record system, being strict, the Dict library, dropping the Data and Control prefixes in standard libraries, allowing modules to be accessed without an import, and the potential divergence on type annotations, I am increasingly okay with not following Haskell's lead here.

Does anyone have thoughts on this? It is definitely a small thing, but I think it is important to avoid adding unnecessary abstraction (which I think Maybe adds).

John Mayer (gmail)

unread,
Feb 3, 2013, 11:39:51 AM2/3/13
to elm-d...@googlegroups.com
I really like Some | None as the constructors for pattern matching. If the type could be 'a?' in addition to 'Option a', that would be really cool. Reminds me of C#, but rather than check for null you'd do the pattern matching.

I think a lot more code in the standard library would benefit from using Option semantics a bit more, and in my code yesterday I found that if that were the case, it would also be convenient to have an andThenMaybe function (I can deal with not having do syntax and just going with explicit bind-chain lambdas for now).

Sent from my iPhone
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Martin DeMello

unread,
Feb 3, 2013, 2:52:41 PM2/3/13
to elm-d...@googlegroups.com
Personally, I really like the name Maybe, possibly because I did
Haskell first, but mostly because I think of its primary use as a
return value rather than a record field. where "Maybe" reads really
nicely. Some is definitely a lot better than Just though.

martin

Evan Czaplicki

unread,
Feb 3, 2013, 3:37:47 PM2/3/13
to elm-d...@googlegroups.com
The `a?` syntax is really cool! It worries me a bit though, especially for larger optional things:

Dict Int String? /= (Dict Int String)?

John, are you doing something like this? Can you talk more about where to use Option more? Like for head and tail?

Martin, I didn't think of it in terms of a return value, but that definitely makes sense, especially when you'll use monads to keep them out of arguments. I agree that (readInt :: String -> Maybe Int) reads better than (readInt : String -> Option Int). Hmm...

I am beginning to think that the question mark reads best in both contexts though. (readInt : String -> Int?)

I'm going to do a visual experiment based on some of Grzegorz's code from Preselm:

type HaskellyFrame = {
  background  :: Maybe Color,
  column1     :: Maybe String,
  column2     :: Maybe String,
  columnWidth :: Maybe Float,
  content     :: Maybe Element,
  ...}

type MLyFrame = {
  background  : Option Color,
  column1     : Option String,
  column2     : Option String,
  columnWidth : Option Float,
  content     : Option Element,
  ...}

type CSharpyFrame = {
  background  : Color?,
  column1     : String?,
  column2     : String?,
  columnWidth : Float?,
  content     : Element?,
  ...}

The question mark is definitely going to be confusing for new-comers, especially if they have an imperative background. It is extremely concise and pretty though.

I am undecided on this one so far. It seems like we agree about (Some a | None) at least?

John Mayer

unread,
Feb 3, 2013, 3:50:39 PM2/3/13
to elm-d...@googlegroups.com
If that indentation currently works in Elm, that I'd be very happy writing in that style. But yes that's exactly what I as referring to.

I do think the question mark is really nice looking. I think newcomers will easily recognize what it means; the friction would probably be in learning to pattern-match to test failure, rather than checking some null value. Of course, a monad-like pattern hides this, for better or for worse!

Martin DeMello

unread,
Feb 3, 2013, 4:05:20 PM2/3/13
to elm-d...@googlegroups.com
One possible source of confusion is that scheme (and ruby, which was
scheme-inspired) use a ? at the end of function names to signify that
they return a boolean.

Also, one more option (npi) to toss into the mix (call it Rusty for
want of a better name, since their ongoing syntax experiments seem to
be keeping all sigils at the front):

type RustyFrame = {
background : ?Color,
column1 : ?String,
column2 : ?String,
columnWidth : ?Float,
content : ?Element,
...}

Cons: Looks a bit dissonant, possibly even ugly, since in English ?s
attach to the end of things.

Pros: One thing I really dislike about OCaml is that they use 'a
option rather than option 'a - it reads far better for the qualifiers
to precede the type.

martin

Izzet Pembeci

unread,
Feb 3, 2013, 5:05:32 PM2/3/13
to elm-d...@googlegroups.com
Just comparing these two I prefer Maybe as the type name and Some/None as constructors. I think Option only refers to a specific usage of these kind of values and limits the interpretation (as the readInt example demonstrates). I like using ? for predicates:

if alive? ...
if (mario 'collides?' item) ...

so I am reading Int? as 'is Int?' and it doesn't make much sense. I wonder if there may be a better option than Maybe:


type Frame = { background  :: Expected Color, ...
readInt :: String -> Expected Int

type Frame = { background  :: Presume Color, ...
readInt :: String -> Presume Int

iZzeT

John Mayer (gmail)

unread,
Feb 3, 2013, 5:20:32 PM2/3/13
to elm-d...@googlegroups.com
That's interesting, what language are you using that allows you to use '?' in an identifier?

Sent from my iPhone

Izzet Pembeci

unread,
Feb 3, 2013, 5:49:23 PM2/3/13
to elm-d...@googlegroups.com
As Martin mentioned Scheme allows that (some DrRacket examples) . Also in some logo dialects like Netlogo it is widely used (examples just ctrl-f for ?).

iZzeT

Evan Czaplicki

unread,
Feb 3, 2013, 8:36:19 PM2/3/13
to elm-d...@googlegroups.com
I don't think having it at the front works visually. The reasoning makes sense, but I think it'd be better to just go without if that's what any Maybe would look like.

It is kind of cool to have ? as a character for defining variables, but I'd need to see more code. Their libraries sometimes have two versions of a function (member and member?) when the question mark does not feel quite necessary. Is the rule "put it on anything that returns a bool"?

My sense was that Schemers are not super into upper case letters or any other obvious use of the shift key. I believe they allow - in variable names partly to avoid pressing shift for _ or a capital letter.

Maybe it would be good to have some representative test program that we would write in each of these styles?

Now that I have seen the benefits of Maybe, I am thinking (data Maybe a = Some a | None) is kind of nice. The danger is that it messes with both .hs and .ml people. I'm inclined to wait on a decision for ? though until we can look at more possibilities. It may also be useful for implicits? Agda uses {} for this which would not work for us.

Grzegorz Balcerek

unread,
Feb 4, 2013, 1:53:55 PM2/4/13
to elm-d...@googlegroups.com
Hi,

My 2 cents:

I do not have a problem with Maybe/Just/Nothing. I am also used to
Option/Some/None in Scala.  I would recommend to stick with one of
those two options instead of introducing a third one, like
Maybe/Some/None.  Actually Optional is also nice (maybe even better
then Option), so I am also fine with Optional/Some/None.

I am against adding new syntax for things that can be expressed with
the standard library.  So, I am against adding the question mark as a
special syntax.

However, if you really like the question mark, then I would suggest
adding it to the standard library as an identifier instead of as
syntax.  That would require allowing the question mark characters in
identifiers and just renaming Maybe to ?

You would then be able to write

 color : ? Color

instead of

 color : Maybe Color

without introducing a special syntax for optional values.  You could
also write

 color : ?Color

(without the space) if you disallow mixing operator characters with
regular characters in identifiers.  By the way, Scala allows using
operators in identifiers, including the quotation mark, so for example
? is a valid identifier in Scala. Color is also a valid idenfier in
Scala. However ?Color is not. Another example: there is a method
called ??? which has the type of Nothing, which is the bottom type in
Scala, and which just throws an exception. It may be used as a
placeholder for methods which are not implemented yet (for example in
exercises) without causing compilation errors.

I like using : for type annotations and :: for list consing. This is
also the Scala way.

I would suggest not make design decisions based on the fear that
something might be confusing for newbies. Of course newbies might be
confused. They are newbies after all. However, a tutorial is a place
to address it, not syntax. Syntax is for regular users.

Grzegorz

Grzegorz Balcerek

unread,
Feb 4, 2013, 2:32:00 PM2/4/13
to elm-d...@googlegroups.com

If you like the approach of renaming Maybe (or Option or Optional) to ? then you could also consider renaming Eihter to ∨

Or rather then renaming making them both aliases.

You could then write

x : Maybe Int 

or 

x : ? Int

and you could also write

x : Either String Int

or (using infix notation)

x : String ∨ Int

Grzegorz

John Mayer (gmail)

unread,
Feb 4, 2013, 2:37:28 PM2/4/13
to elm-d...@googlegroups.com
I think there's a benefit to writing the question mark first. ?Type is still a very small amount of key presses, but it's also "different" to what we're used to. I think that's a useful quality in syntax, from a linguistic point of view. Perl does this for similar reasons in how it uses $foo, @foo, and %foo to denote scalar, array, and hash variables.

In that spirit I'd just make the '?' the only named type constructor, throwing out maybe and option altogether, and using Some/None as the data constructors for matching.

Sent from my iPhone

John Mayer (gmail)

unread,
Feb 4, 2013, 2:49:16 PM2/4/13
to elm-d...@googlegroups.com
I don't have one of those on my keyboard ;-)

Finally, there's the option of making "?" a type synonym for "Either ()", the error type without error messages.

Sent from my iPhone

Grzegorz Balcerek

unread,
Feb 4, 2013, 3:11:31 PM2/4/13
to elm-d...@googlegroups.com



I don't have one of those on my keyboard ;-) 

Me neither. That is why I think it is better to make aliases instead of just renaming.

Grzegorz

Dobes Vandermeer

unread,
Feb 6, 2013, 2:22:42 AM2/6/13
to elm-d...@googlegroups.com
My reaction:

The idea of putting ? on the end is interesting, it was the first thing that came to mind when I started to read this thread.

I don't think you'll find a clear winner in terms of changing between particular English words like Maybe, Optional, Option, Some, None, Nothing, Null, None, Present, Absent, Alpha, Beta, and so on.  If you consider your target audience and what term they are most familiar with (i.e. which language they came from) then you can go with that.  Otherwise I don't see much value in changing.  Perhaps you can just support them all - set None = Nothing = Null and Some = Just - but that seems like a but of namespace pollution.

If someone really has a lot of optional fields you could provide a way for them to create their own alias for it, like 

type Element? = Option Element
type alias Opt = Maybe

Scheme does have this "?" suffix thing for predicate functions because they like to have a constructor function that makes something ... like "b = Just a" ... and then check for whether it is that thing "if Just? b".  It is a cute convention, but the "is-" prefix works just as well in my opinion and is more friendly to language agnostic editors that assume alphanumeric identifiers (i.e. if you double-click it will select the whole word but not the "?", unless it's a scheme specific editor).

Unicode characters are fun but seem to be hard to use.  I thought I had gotten that lambda unicode character thing working in my editor but when I tried to compile it rejected it, so there must be some sort of encoding issue going on that I haven't sorted out yet.  Having some percentage of new users going through that process (even given an alternative) has some cost to it, although not a cost I can really estimate the impact of.




On Sun, Feb 3, 2013 at 2:15 AM, Evan Czaplicki <eva...@gmail.com> wrote:

--

Evan Czaplicki

unread,
Feb 6, 2013, 2:42:07 PM2/6/13
to elm-d...@googlegroups.com
I actually just added type aliases in the dev version, so that will be possible very soon.

I hadn't considered the editor issues that would come up with ?, but that is a good point.

I just found a paper on implicits in Agda that seems to solve some of the issues in Scala. I'd like to hold off on using ? until I have a better handle on the ideas there. They all use {} syntax to indicate that the type checker should infer an argument, which is not really possible for Elm. I'm thinking ? might be a reasonable choice here as it really would be a semantically new feature.

I have very mixed feelings about changing the names. Perhaps I'll just try it in some files and see how it feels. It know it's a low value thing, but Maybe just bugs me for some reason :P I think it's safe to assume it'll stay as is for now though.
Reply all
Reply to author
Forward
0 new messages