Introduction. I think it's useful to first discuss the difference in the simple example as it helps to understand what "unit" value is. The first declaration creates a string value (and immediately calls ReadLine to obtain the input from the user):
> let readLine = Console.ReadLine ();;
val readLine : string
The second declaration creates a function that takes unit value as an argument. The function doesn't need to take any input, but we want to define it as a function, so that it can be executed repeatedly (we need that, because the function has side-effect - it reads input from the user).
The "unit" parameter is just a way of creating a function that takes something as argument. "Unit" has only a single value written as (), so it doesn't represent any information - just the fact that there is some parameter:
> let readLine () = Console.ReadLine ();;
val readLine : unit -> string
Your question. To look at your example with additional braces. This creates a function that takes a string as the first parameter and takes additional "unit" value as the second parameter. You can see that from the type signature:
> let print (text : string) () = Console.WriteLine text
val print : string -> unit -> unit
This is valid F# declaration, but it is not very useful. It means that the function will be only called when you give it some string to print and also additional "unit" value. You can call it like this:
print "Hello" ()
Even without the additional "unit" parameter, it would be a function (as opposed to a value), so adding the additional parameter doesn't help (you're always creating a function that can be called to print different strings).
There are still cases where this declaration can be interesting. For example, you can call the function just with the string as a parameter. In this case, you'll get a function as the result. The returned function will take unit and will print the string:
let f = print "Hello" // doesn't print anything
f () // prints "Hello"
f () // prints "Hello" again!
So, the compiler allows you to use "unit" values as any other values in the language. This includes uses that may look a bit unfamiliar (and not very useful) at first, but can make a good sense in some scenario.
printas the name of the function, when a better name ismakePrinter, since it takes a string and returns a function that will print that string.