/* == definition == */ | |
/* two labelled arguments, one unlabelled */ | |
let display = (~message, ~person, time) => 1; | |
/* with default value */ | |
let display = (~message="hello", ~person="Reason", time) => 1; | |
/* with type annotation */ | |
let display = (~message: string, ~person: string, time: float) => 1; | |
/* type annoation and with default */ | |
let display = (~message: string="hello", ~person: string="Reason", time: float) => 1; | |
/* == call == */ | |
/* normal */ | |
display(~message="hey", ~person="Reason", 2.0); | |
/* call with punning, aka ~message=message */ | |
display(~message, ~person, 2.0); | |
/* == type definition == */ | |
/* normal */ | |
type d = (~message: string, ~person: string, float) => int; | |
/* with default */ | |
type d = (~message: string=?, ~person: string=?, float) => int; |
/* == definition == */ | |
/* two labelled arguments, one unlabelled */ | |
let display = (:message, :person, time) => 1; | |
/* with default value */ | |
let display = (:message="hello", :person="Reason", time) => 1; | |
/* with type annotation */ | |
let display = (:message: string, :person: string, time: float) => 1; | |
/* type annoation and with default */ | |
let display = (:message: string="hello", :person: string="Reason", time: float) => 1; | |
/* == call == */ | |
/* normal */ | |
display(:message="hey", :person="Reason", 2.0); | |
/* call with punning, aka :message=message */ | |
display(:message, :person, 2.0); | |
/* == type definition == */ | |
/* normal */ | |
type d = (:message: string, :person: string, float) => int; | |
/* with default */ | |
type d = (:message: string=?, :person: string=?, float) => int; |
Adding types to a function often makes the code much simpler to understand, so we should make it as simple as possible to write type signatures
Prefer #2 partly because it reminds me of Smalltalk
#1 for sure, number 2 feels confusing to have the preceding : then also using it to separate from the type.
That said... I agree with @cullophid
:
usually has real semantic meaning, that other characters wouldn't have: in English, it's often used to separate a "key" clause (short, tl;dr) from a "descriptive" clause. In Objective-c it's functionVariableName: functionVariableArgument
. In Javascript it's key: value
inside of objects. Putting it in the front results in :key=value
which reverses the typical meaning. ~
's only semantic meaning, that I think is commonly used, is "approximately" in math. As such, it's probably a better character to overload with meaning, especially as it seems (to me) to have fewer major-language (JS especially) meaning clashes.
Maybe consider the possibility to use one of the both for an other sugar, this might make the decision for this one easier.
Calling a function using parenthesis destroys the beauty of currying syntax
Agree with @fstiffo : Why create more verbose syntax ?
About the initial question I prefer the first one (~) like in OCaml
The second (:) may be confusing about the meaning of ':' symbol in ReasonML
I prefer ~
over :
only because :
is already meaningful for types - wouldn't want to overload that meaning.
I vote for
/* two labelled arguments, one unlabelled */
let display = (@message, @person, time) => 1;
/* with default value */
let display = (@message="hello", @person="Reason", time) => 1;
/* with type annotation */
let display = (@message: string, @person: string, time: float) => 1;
/* type annoation and with default */
let display = (@message: string="hello", @person: string="Reason", time: float) => 1;
/* == call == */
/* normal */
display(@message="hey", @person="Reason", 2.0);
/* call with punning, aka @message=message */
display(@message, @person, 2.0);
/* == type definition == */
/* normal */
type d = (@message: string, @person: string, float) => int;
/* with default */
type d = (@message: string=?, @person: string=?, float) => int;
Tilde please. Like others have said, I think overloading the meaning of symbols is not a wise thing to do. The tilde is unique and while it might seem weird the first 5 times a newcomer looks at it, it is easy to digest. Thowing :
everywhere is awfully confusing.
Both make the functions difficult to read:(
Would it not be preferable to separate the type signature from the definition? Like in elm/haskell?
I know this isn't the topic here, but I think that's why this is so complicated