3

Can we create a function with void (i.e with no return value) in functional languages? Like Haskell or Scheme

Jeff Yan
  • 309
  • 1
  • 3
  • 9
  • 1
    What would a function without a return value do in Haskell? – Rein Henrichs Dec 01 '17 at 04:14
  • I'm not sure I'm following the question. if something has no return type, why's it a function? – Zooby Dec 01 '17 at 04:15
  • Sort of. Ignoring implementation details, you can think of `void` as being a return type that has exactly one inhabitant. Haskell chooses to make that sort of thing explicit - our `void` is `()`. – Alec Dec 01 '17 at 04:15
  • Like in Java, we have the void method.We just do some operation, but no return value – Jeff Yan Dec 01 '17 at 04:16
  • 3
    You can't do such operations in Haskell. It is a pure language. A function without a return value (or one that returns `()`, as Alec suggests) wouldn't do anything at all. – Rein Henrichs Dec 01 '17 at 04:18

5 Answers5

9

In Haskell, you can write a whole family of functions that return () (unit), which is equivalent to void in C languages:

foo :: a -> ()
foo _ = ()

bar :: a -> b -> ()
bar _ _ = ()

You'll notice, however, that my implementations ignore their input, and simply return (), so they don't do anything.

You can call them like this:

Prelude> foo 42
()
Prelude> bar 42 "foo"
()

but this still doesn't accomplish anything.

You can, on the other hand, write functions that return IO (), like this:

main :: IO ()
main = putStrLn "Hello, world!"

but this is now impure. While this produces a side-effect, you could argue whether or not it's functional. At the very least, in Haskell, you can't call impure code from pure code (this is by design), so it doesn't compose.

Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
  • I think there's a connection between functions to `void` and polymorphic null data constructors. One could think of `Nothing` as a function from a type to `()`. – chepner Dec 01 '17 at 13:00
4

What would the purpose be of such a function? Also if you think of a mathematical function (the base of functional programming) what would be the codomain of such a function?

So the short answer is no in haskell (i don't know enough scheme to give an informed answer regarding that).

The closest thing to void in java in haskell would be IO ()

epsilonhalbe
  • 15,637
  • 5
  • 46
  • 74
2

In Racket you can:

Welcome to DrRacket, version 6.11 [3m].
Language: racket, with debugging; memory limit: 128 MB.
> (define (f) (displayln "hello") (void))
> (f)
hello
> (void? (f))
hello
#t
uselpa
  • 18,732
  • 2
  • 34
  • 52
2

First, you need to remember that programming languages tend to use the word "function" in a sense that is different from the mathematical meaning. A programming-language function is just a named subroutine that may or may not produce a value that can be assigned or passed around.

Pascal made somewhat of a distinction between a "real" function and one that returned no value; the keyword procedure creates a subroutine that returns nothing, the keyword function has to return a value of some type.

C is an example that blurs this distinction; a function can have a return value of type void which in reality is type with exactly one value (although that value isn't actually represented in code; you have to pretend it exists). Every function with this return type always returns that same value. Python makes it a little more explicit; a function with no return statement or a return statement with no value actually returns the singleton value None.

Haskell has a similar type, (), which is inhabited by a single value with the same name. You can of course define a family of functions, one function per type, foo :: a -> () which ignores its argument and returns (). It doesn't have any practical value (as a pure language, a function can't do anything except return a value of its declared return type), but it does indeed exist. foo _ = ().

Incidentally, the functions of type a -> () establish () as the terminal object in the (pseudo)category Hask, which is necessary for establishing Hask as a cartesian-closed category, making it suitable for defining the semantics of Haskell.


However, Haskell also does have a type that contains no values, appropriately called Void:

data Void

Since Void is a valid type, you can imagine a type that contains functions from Void to any other type:

absurd :: Void -> a

However, since there are no values of type Void, you can't really call such a function. The unique function of type Void -> a can be defined as

absurd x = case x of {}  -- There's nothing x *can* match

This is not to say that absurd has no use at all, just no practical use. Just as functions of type a -> () define () as the terminal object in Hask, absurd defines Void as the initial object in Hask.

(The latter half of this answer is a (bad) synopsis of information found in Bartosz Milewski's fantastic series of posts Category Theory for Programmers.)

chepner
  • 497,756
  • 71
  • 530
  • 681
  • [`absurd`](http://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Void.html#v:absurd) is actually `Void -> a`, not the other way around. `Void` is the _initial_ object of **Hask**; the terminal object is `()`. – leftaroundabout Dec 01 '17 at 13:52
  • Sigh. That's what I get for trying to write this from memory. – chepner Dec 01 '17 at 13:53
  • 2
    Also, you _can_ define `absurd`; basically the only way to do it is the (empty but exhaustive!) case match `absurd x = case x of {}`. That's the point: there exists precisely one function `Void -> a`, like there is exactly one function `a -> ()`. This being the requirement of an initial / terminal object. – leftaroundabout Dec 01 '17 at 22:15
  • Yes, `absurd` is perfectly well defined and non-absurd in and of itself. It's the implications of actually *calling* it that are absurd, which you can't do without "cheating" since you need to first obtain a value of type `Void`. – Ben Dec 01 '17 at 23:43
0

In Haskell the only thing a function does is to return a value.

If a function doesn't return anything, then what the heck does it actually do?

You're probably thinking about something like a print "function", which prints something out and returns nothing. But that's not a mathematical function, that's an action. Haskell models those in a completely different way (i.e., monads). If you want to know what that is, there's elevanty billion discussions about it here on Stack Overflow, and littered across the face of the Internet.

MathematicalOrchid
  • 61,854
  • 19
  • 123
  • 220