Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

For instance, in Haskell a value is a value. If I have a value of type Integer then it definitely exists; if I want to say that it might not exist then I use the type "Maybe Integer", which expresses that idea precisely.

Same goes for a value of type Employee; if I might or might not have an Employee (for instance, if the lookup function doesn't find someone with that employee number) then I have to use Maybe Employee.

Scala has the same concept with (IIRC) the Option type. But Scala also inherits null references from Java. In Java a reference to an Employee might be an optional value (so null is allowed) or it might be a required value (so null is not allowed). Scala has to play well with Java so anything has to be allowed to be a null reference. Except that Integers in Java (and hence Scala) aren't references, so I can't have a null reference to an Integer.

So now my "Option Employee" might wind up being a null reference to the Option, or it might be an Option that is empty, or it might be an Option that contains a null reference to the Employee, or it might actually have an Employee in it.

Gahh.



> in Haskell a value is a value

The same is true of C++. Values and references in C++ can't be null. Pointers can be null, but that's a lower-level feature that doesn't have an equivalent in idiomatic Haskell.


"Ptr a" is an equivalent, in many senses. It's quite true that use is far less in idiomatic Haskell, especially as you're restricted to IO when operating on them.


Ptr is exactly the same thing as a C pointer. Critically, if you have a Ptr to some value, that Ptr could become invalid if the value gets moved by the garbage collector, just like a C pointer would. That's why you'd never use Ptr except in FFI code, to access memory that isn't managed by Haskell's GC. (If you need to pass a pointer to a Haskell value to code written in another language, you'd use a StablePtr, which pins the value in the Haskell heap.)

In idiomatic Haskell, if you need something like a pointer you have several choices. If you're writing parallel code your best bet is STM. If you're writing code in IO, you can use an IORef. If you don't want that restriction, you can use an STRef.

(I'm aware that you probably know all this, but other people reading the thread might not.)


Right, it's "exactly the same thing" under the hood. It's different in the roles it serves. Your elaboration is appreciated!


It's worth noting that `Option(null)` is `None`. And while it's possible for any reference to be assigned `null`, it rarely happens in Scala code as a) it's well known to be bad form, and b) the IDE's can be configured to yell at you about it. Practically speaking (from the middle), it's not a problem.


>For instance, in Haskell a value is a value. If I have a value of type Integer then it definitely exists;

    x,y::Integer
    x = x + 1
    y = undefined


`undefined` is used as a placeholder for yet to be written code; since you cannot do anything meaningful with it, it is never used in practice.


That's an important point, but since you can't test for undefined-ness it's not quite the same thing as carrying around something that's actually a Maybe Int but just hopes you'll check before implicitly using fromJust everywhere.


We just don't want to forget that exceptions and termination are effects, and that Haskell isn't perfectly pure...

    a,b::Integer
    a = div 1 0
    b = sum [1..]


Certainly the case.


If you want to avoid partial functions, I guess you would use Safe Haskell.


AFAIK, Safe Haskell doesn't do that. Am I missing something?


You're probably right. I can't find any mention of enforcing total functions.


Probably you mean the 'safe' package.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: